Как получить два списка при помощи Stream API?
А именно. Имеется список неких объектов Cat:
public class Cat {
LocalDate birthDay;
int weight;
}
При помощи Stream API я хочу разбить их на две категории по следующему параметру:
берём условного cat1 из списка. Если вес всех котов, которые родились в то же время, что и наш кот, больше 100, добавляем его в карту под ключом false, а если меньше или ровно, то в карту под ключом true.
На выходе должна получиться карта Map<Boolean, List<Cat>>. Для таких вещей в Stream API существует метод partitioningBy(), но с ним я могу разделять котов только относительно того, удовлетворяет ли их собственный вес условию, а мне надо, чтобы коты разделялись относительно того, удовлетворяет ли сумма веса всех котов, которые родились с рассматриваемым котом, определённому условию.
Объясните, как такое можно сделать:
- Не используя сторонние коллекции.
- Не меняя класс.
- Желательно, без собственной реализации
Collector.
Ответы (2 шт):
Первым шагом подсчитываем общий вес по дням, а уже потом просто разделием всех котов.
package com.somepackage;
import lombok.Builder;
import lombok.Data;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Stream;
import static java.util.stream.Collectors.*;
class Main {
@Data
@Builder
public static class Cat {
LocalDate birthDay;
int weight;
}
public static void main(String[] args) {
Set<Cat> cats =
Stream.of(
Cat.builder()
.birthDay(LocalDate.now().minusDays(1))
.weight(100)
.build(),
Cat.builder()
.birthDay(LocalDate.now().minusDays(1))
.weight(200)
.build(),
Cat.builder()
.birthDay(LocalDate.now())
.weight(50)
.build()
).collect(toSet());
Map<LocalDate, Integer> weightByDate =
cats.stream()
.collect(groupingBy(Cat::getBirthDay, summingInt(Cat::getWeight)));
Map<Boolean, List<Cat>> catsByCondition =
cats.stream()
.collect(partitioningBy(c -> weightByDate.get(c.getBirthDay()) < 100));
System.out.println(catsByCondition);
}
}
Результат:
{false=[Main.Cat(birthDay=2020-09-16, weight=100), Main.Cat(birthDay=2020-09-16, weight=200)], true=[Main.Cat(birthDay=2020-09-17, weight=50)]}
Можно сделать так:
Map<Boolean, List<Cat>> sortedCats = cats.stream().collect(Collectors.groupingBy(
cat -> cats
.stream()
.filter(cat1 -> cat1.birthDay.equals(cat.birthDay))
.collect(Collectors.summingInt(o -> o.weight))
.intValue() > 100
));