Каков наилучший способ разделить коллекцию на две разные коллекции?
У меня есть набор чисел:
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);
}