Как разделить список по условию с помощью потоков 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 и собрать элементы, основанные на условиях.

793   1  

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.

Comments

    Ничего не найдено.