31

I have a list a which i want to split to few small lists.

say all the items that contains with "aaa", all that contains with "bbb" and some more predicates.

How can I do so using java8?

I saw this post but it only splits to 2 lists.

public void partition_list_java8() {

    Predicate<String> startWithS = p -> p.toLowerCase().startsWith("s");

    Map<Boolean, List<String>> decisionsByS = playerDecisions.stream()
            .collect(Collectors.partitioningBy(startWithS));

    logger.info(decisionsByS);

    assertTrue(decisionsByS.get(Boolean.TRUE).size() == 3);
}

I saw this post, but it was very old, before java 8.

Community
  • 1
  • 1
Elad Benda
  • 35,076
  • 87
  • 265
  • 471
  • 3
    A predicate is boolean. It just has "true" and "false". I think it would be better to use a `Function` and `Collectors::groupingBy` in your case. – RealSkeptic Apr 17 '16 at 15:43

2 Answers2

41

Like it was explained in @RealSkeptic comment Predicate can return only two results: true and false. This means you would be able to split your data only in two groups.
What you need is some kind of Function which will allow you to determine some common result for elements which should be grouped together. In your case such result could be first character in its lowercase (assuming that all strings are not empty - have at least one character).

Now with Collectors.groupingBy(function) you can group all elements in separate Lists and store them in Map where key will be common result used for grouping (like first character).

So your code can look like

Function<String, Character> firstChar =  s -> Character.toLowerCase(s.charAt(0));

List<String> a = Arrays.asList("foo", "Abc", "bar", "baz", "aBc");
Map<Character, List<String>> collect = a.stream()
        .collect(Collectors.groupingBy(firstChar));

System.out.println(collect);

Output:

{a=[Abc, aBc], b=[bar, baz], f=[foo]}
Community
  • 1
  • 1
Pshemo
  • 122,468
  • 25
  • 185
  • 269
7

You can use Collectors.groupingBy to turn your stream of (grouping) -> (list of things in that grouping). If you don't care about the groupings themselves, then call values() on that map to get a Collection<List<String>> of your partitions.

yshavit
  • 42,327
  • 7
  • 87
  • 124