将集合划分为2个不同集合的最佳方法是什么?

时间:2018-02-06 17:02:15

标签: java filter java-8 java-stream data-partitioning

我有一组数字:

 Set<Integer> mySet = [ 1,2,3,4,5,6,7,8,9]

我想把它分成两组赔率和赔率。

我的方法是使用过滤器两次:

Set<Integer> set1 = mySet.stream().filter(y -> y % 2 == 0).collect(Collectors.toSet())
Set<Integer> set2 =mySet.stream().filter(y -> y % 2 != 0).collect(Collectors.toSet())

我不喜欢这个解决方案,因为我经历了两次整套。

有没有更聪明的方法呢?

6 个答案:

答案 0 :(得分:38)

Map<Boolean, List<Integer>> partitioned = 
    set.stream().collect(Collectors.partitioningBy(x -> x%2 == 0));

partitioned.get(true)中的元素是偶数; partitioned.get(false)中的元素是奇数。

与使用groupingBy执行此操作不同,可以保证truefalse列表都会出现在地图中,即使它们是空的。 (Java 8中没有记录,但确实如此; Java 9的doc现在明确说明了这一点。)

答案 1 :(得分:13)

简单循环和if / else将是一个干净而简单的解决方案

Set<Integer> setEven = new HashSet<>();
Set<Integer> setOdd = new HashSet<>();

for (Integer val : mySet) {
    if (val % 2 == 0)
        setEven.add(val);
    else
        setOdd.add(val);
}

使用ternary operator可以更好地简化代码

for(Integer val : mySet) {
    ((val % 2 == 0) ? setEven : setOdd).add(val);
}

答案 2 :(得分:13)

您可以使用下面的Collectors#partitioningBy

Map<Boolean,List<Integer>> evenOddMap  = mySet.stream().collect(Collectors.partitioningBy(e -> e % 2 == 0));
System.out.println("Even : "+evenOddMap.get(true));
System.out.println("Odd : "+evenOddMap.get(false));

答案 3 :(得分:11)

您可以使用Collectors.partitioningBy

        Map< Boolean, Set<Integer> > map =
        mySet.stream().collect( Collectors.partitioningBy( y -> y % 2 == 0, 
        Collectors.toSet() ) );

        Set<Integer> odds = map.get(Boolean.TRUE);
        Set<Integer> evens = map.get(Boolean.FALSE);

修改

我看到有几个类似的答案。这里的细微差别在于它显示了如何将集合设置为Set而不是List,以防OP想要这样。

答案 4 :(得分:1)

如果您已拥有保存值的集合,则以下内容可以作为解决方案。

data.stream().forEach(x -> {
if(x%2==0){
//add to collection holding even nums
} else {
//add to collection holding odd nums
}
})

答案 5 :(得分:0)

您可以使用groupingBy

public void test(String[] args) {
    Integer[] test = {1,2,3,4,5,6,7,8,9};
    Map<Integer, List<Integer>> evenOdd = Arrays.stream(test).collect(Collectors.groupingBy(i -> i & 1));
    Set<Integer> evens = new HashSet<>(evenOdd.get(0));
    Set<Integer> odds = new HashSet<>(evenOdd.get(1));
    System.out.println("Evens "+evens+" Odds "+odds);
}