I have OrderItems class
public class OrderItems {
public int id;
public double portion;
and List<OrderItems>
like below:
List<OrderItems> orderItems = new ArrayList<>();
orderItems.add(new OrderItems(1,0.5));
orderItems.add(new OrderItems(2,1));
orderItems.add(new OrderItems(1,0.5));
orderItems.add(new OrderItems(1,1.5));
orderItems.add(new OrderItems(2,1));
orderItems.add(new OrderItems(2,0.5));
My Question :
How can i group this list and convert NewOrderItems
class with Stream API:
public class NewOrderItems {
public int id;
public double portion;
public long amount;
}
Result should be like this:
NewItems{id=1, portion=0.5, amount=2}
NewItems{id=1, portion=1.5, amount=1}
NewItems{id=2, portion=0.5, amount=1}
NewItems{id=2, portion=1.0, amount=2}
CodePudding user response:
first groupby. you will get a Map. OrderItems as key, List as value. then count it. last sort it.
check where you can't understand.
public static void main(String[] args) {
List<OrderItems> orderItems = new ArrayList<>();
orderItems.add(new OrderItems(1, 0.5));
orderItems.add(new OrderItems(2, 1));
orderItems.add(new OrderItems(1, 0.5));
orderItems.add(new OrderItems(1, 1.5));
orderItems.add(new OrderItems(2, 1));
orderItems.add(new OrderItems(2, 0.5));
final List<NewOrderItems> collect = orderItems.stream().collect(Collectors.groupingBy(x -> x))
.entrySet().stream().map(x -> {
NewOrderItems newOrderItems = new NewOrderItems();
newOrderItems.setId(x.getKey().id);
newOrderItems.setPortion(x.getKey().portion);
newOrderItems.setAmount(x.getValue().size());
return newOrderItems;
})
.sorted(new Comparator<NewOrderItems>() {
@Override
public int compare(NewOrderItems o1, NewOrderItems o2) {
return o1.id - o2.id;
}
})
.collect(Collectors.toList());
System.out.println(collect);
}
CodePudding user response:
We can make use of
- Collectors.groupingBy -> for grouping the order item
- Java record -> to define the key for grouping
- Collectors.reducing -> combine order item list of each group
public class GroupItem {
public static void main(String[] args) {
List<OrderItems> orderItems = new ArrayList<>();
orderItems.add(new OrderItems(1, 0.5));
orderItems.add(new OrderItems(2, 1));
orderItems.add(new OrderItems(1, 0.5));
orderItems.add(new OrderItems(1, 1.5));
orderItems.add(new OrderItems(2, 1));
orderItems.add(new OrderItems(2, 0.5));
// java 17 feature to define key easily
record ItemKey(int id, double portion) {
}
Map<ItemKey, GroupedOrderItems> m = orderItems.stream().collect(
Collectors.groupingBy(
// group by ItemKey
i -> new ItemKey(i.id, i.portion),
// reducing the OrderItems with same key
Collectors.reducing(
new GroupedOrderItems(0, 0.0, 0L),
a -> new GroupedOrderItems(a.id, a.portion, 1),
// combine 2 GroupedOrderItems
(b, c) -> new GroupedOrderItems(c.id,
b.portion c.portion,
b.amount c.amount)
)
)
);
m.entrySet().forEach(e -> System.out.println(e.getValue()));
}
public static class OrderItems {
public int id;
public double portion;
public OrderItems(int id, double portion) {
this.id = id;
this.portion = portion;
}
}
public static class GroupedOrderItems {
public int id;
public double portion;
public long amount;
public GroupedOrderItems(int id, double portion, long amount) {
this.id = id;
this.portion = portion;
this.amount = amount;
}
@Override
public String toString() {
return "GroupedOrderItems{"
"id=" id
", portion=" portion
", amount=" amount
'}';
}
}
}