分组列表<OrderItems>和计数

问题描述 投票:0回答:3

我有 OrderItems 类

public class OrderItems {
    public  int id;
    public  double portion;

List<OrderItems>
如下所示:

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));

我的问题: 我如何对该列表进行分组并使用 Stream API 转换

NewOrderItems
类:

   public class NewOrderItems {
      public int id;
      public double portion;
      public long amount;
   }

结果应该是这样的:

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}
java list stream group
3个回答
0
投票

我的解决方案是这样的:

Map<Integer, Map<Double, Long>> collect = orderItems.stream()
                    .collect(Collectors.groupingBy(OrderItems::getId, Collectors.groupingBy(OrderItems::getPortion, Collectors.counting())));
            System.out.println(collect);

            List<NewOrderItems> newOrderItems = new ArrayList<>();

            collect.forEach((k,v)->{
                    v.forEach((x,y)->{
                           NewOrderItems newOrderitems=new NewOrderItems(k,x,y);
                           newOrderItems.add(newOrderitems);
                    });
            });
            newOrderItems.forEach(System.out::println);

控制台:

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}

0
投票

首先分组。你会得到一张地图。 OrderItems 作为键,List 作为值。然后算一下。最后排序。

看不懂的地方。

    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);
    }

0
投票

我们可以利用

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,
                                        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 +
                    '}';
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.