Подтвердить что ты не робот

Как отделить список по условию с использованием потоков Java 8

Рассмотрим следующий код:

 List<Integer> odd = new ArrayList<Integer>();
 List<Integer> even = null;  
 List<Integer> myList = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
 even = myList.stream()
              .filter(item -> {
                   if(item%2 == 0) { return true;}
                   else { 
                           odd.add(item); 
                           return false;
                   }
              })
              .collect(Collectors.toList());

То, что я пытаюсь сделать здесь, это получить четные и нечетные значения из списка в отдельные списки.

Метод stream filter() возвращает true для четных элементов, и сборщик потоков будет их собирать.
Для нечетного случая фильтр вернет false, и элемент никогда не достигнет коллектора.

Итак, я добавляю такие нечетные числа в другой список, который я создал ранее в блоке else.

Я знаю, что это не элегантный способ работы с потоками. Например, если я использую параллельный поток, тогда будет проблема с безопасностью потока с нечетным списком. Я не могу запускать его несколько раз с разными фильтрами из-за причин производительности (должен быть O (n)).

Это всего лишь пример для одного случая использования, список может содержать любой объект, а лямбда внутри фильтра должна отделять их на основе некоторой логики в отдельные списки.

В простых терминах: из списка создайте несколько списков, содержащих элементы, разделенные на основе некоторых критериев.

Без потоков было бы просто запустить цикл for и выполнить простой if-else и собрать элементы на основе условий.

4b9b3361

Ответ 1

Вот пример того, как вы можете разделить элементы (числа) этого списка на четные и нечетные числа:

List<Integer> myList = Arrays.asList(1,2,3,4,5,6,7,8,9,10);

Map<Boolean, List<Integer>> evenAndOdds = myList.stream()
        .collect(partitioningBy(i -> i % 2 == 0));

Вы получили бы списки четных/нечетных чисел (этот список может быть пустым):

List<Integer> even = evenAndOdds.get(true);
List<Integer> odd = evenAndOdds.get(false);

Вы можете передать любую лямбду с требуемой логикой в ​​ partitioningBy.