Каков наилучший способ разделить коллекцию на две разные коллекции?

У меня есть набор чисел:

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

Я хочу разделить его на 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())

Мне не нравится это решение, потому что я перехожу через весь набор дважды.

Есть ли более разумный способ сделать это?

Ответ 1

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 теперь указано это явно).

Ответ 2

Простой цикл, и если /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);
}

Ответ 3

Вы можете использовать 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));

Ответ 4

Вы можете использовать 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 захочет именно так.

Ответ 5

Если у вас уже есть коллекции для хранения значений, ниже может быть решение.

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

Ответ 6

Вы можете использовать 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);
}