'Java stream approach to partition elements based on sum of the object property
Given a List of objects with an integer property, I want to partition the list into multiple lists, grouping the elements by summing them based on a property until a maximum threshold is reached. Is there a supported way to do this with the Java Stream APIs, rather than maintaining the sums/counts in a for loop?
Example desired function:
class Foo {
String id;
int price;
public Foo(String id, int price) {
this.id = id;
this.price = price;
}
public static void main(String[] args) {
List<Foo> list = new ArrayList<>();
list.add(new Foo("one", 1));
list.add(new Foo("two",1));
list.add(new Foo("three",1));
list.add(new Foo("four", 1));
list.add(new Foo("five",2));
list.add(new Foo("six",3));
int maxPrice = 3;
// Expected output: [[{"one", 1"}, {"two", 1}, {"three", 1}], [{"four", 1}, {"five", 2}], [{"six", 3}]]
List<List<Foo>> partitioned = partition(list, maxPrice);
}
private static List<List<Foo>> partition(List<Foo> list, int maxPrice) {
return list.stream()
.????
.collect(???)
}
}
Solution 1:[1]
As mentioned in the comments definitely looks like not the best idea to use streams in this case. However if you really need to, you can use this hardly readable snippet below ;)
private static List<List<Foo>> partition(List<Foo> list, int maxPrice) {
List<List<Foo>> resultList = new ArrayList<>();
List<Foo> tempList = new ArrayList<>();
list.forEach(element -> {
if (tempList.stream()
.reduce(0,
(sum, m) -> {
return sum += m.price;
},
Integer::sum)
+ element.price <= maxPrice) {
tempList.add(element);
} else {
resultList.add(new ArrayList<>(tempList));
tempList.clear();
tempList.add(element);
}
});
resultList.add(new ArrayList<>(tempList));
return resultList;
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | mpdgr |
