Home > Mobile >  Grouping List<OrderItems> and counting
Grouping List<OrderItems> and counting

Time:12-16

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

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  
                    '}';
        }
    }
}
  • Related