web-dev-qa-db-ja.com

コレクションを2つの異なるコレクションに分割する最良の方法は何ですか?

私は数字のセットを持っています:

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

私はそれを2セットのオッズとイーブンに分けたいです。

私の方法は、フィルターを2回使用することでした:

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())

セット全体を2回調べるので、このソリューションは好きではありません。

よりスマートな方法はありますか?

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

partitioned.get(true)の要素は偶数です。 partitioned.get(false)の要素は奇数です。

groupingByを使用してこれを行うのとは異なり、trueリストとfalseリストの両方が空であってもマップに存在することが保証されます。 (Java 8には記載されていませんが、それは真実でした。Java 9のドキュメントでは明示的に述べられています)。

38
Andy Turner

シンプルなループと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);
}

または、 三項演算子 を使用すると、コードがさらに簡素化されます

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

以下のように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));
13
Amit Bera

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);

編集:

同様の回答がいくつかあります。ここでのわずかな違いは、OPがそのように望んだ場合に、リストではなくSetとしてコレクションを取得する方法を示していることです。

11
tsolakp

値を保持するコレクションが既にある場合、以下が解決策となります。

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

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);
}
0
OldCurmudgeon