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