在一个流处理中收集匹配和非匹配?

Tor*_*ist 23 java java-8 java-stream

有没有办法在一次处理中收集匹配和不匹配的流元素?举个例子:

final List<Integer> numbers = Arrays.asList( 1, 2, 3, 4, 5 );
final List<Integer> even = numbers.stream().filter( n -> n % 2 == 0 ).collect( Collectors.toList() );
final List<Integer> odd = numbers.stream().filter( n -> n % 2 != 0 ).collect( Collectors.toList() );
Run Code Online (Sandbox Code Playgroud)

有没有办法避免两次运行数字列表?像"比赛的收藏家和没有比赛的收藏家"这样的东西?

Rav*_*ala 31

你可以这样做,

Map<Boolean, List<Integer>> oddAndEvenMap = numbers.stream()
        .collect(Collectors.partitioningBy(n -> n % 2 == 0));
final List<Integer> even = oddAndEvenMap.get(true);
final List<Integer> odd = oddAndEvenMap.get(false);
Run Code Online (Sandbox Code Playgroud)


Eri*_*ean 9

如果你有超过2组(而不是奇数,甚至在这里使用%2),例如在剩余类%3中对int进行分组,你可以使用一个函数:

Function<Integer, Integer> fun =  i -> i%3;
List<Integer> a = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
Map<Integer, List<Integer>> collect = a.stream().collect(Collectors.groupingBy(fun));

System.out.println(collect);
//{0=[3, 6, 9], 1=[1, 4, 7, 10], 2=[2, 5, 8]}
Run Code Online (Sandbox Code Playgroud)

或者假设您有一个字符串列表,您希望通过启动char来分组,而不是将匹配和非匹配分组(例如,以a开头或不匹配),您可以执行以下操作:

Function<String, Character> fun =  s -> s.charAt(0);
List<String> a = Arrays.asList("baz","buzz","azz","ayy","foo","doo");
Map<Character, List<String>> collect = a.stream().collect(Collectors.groupingBy(fun));

System.out.println(collect);
//{a=[azz, ayy], b=[baz, buzz], d=[doo], f=[foo]}
Run Code Online (Sandbox Code Playgroud)