Java stream流 去重 排序 单字段多字段分组求某个字段总数,用法

 概述

        处理list 数据数据重复 排序问题,有个别情况的分组解决办法(单字段分组或者多字段分组 并且如何带出完整数据)

1.List 数据



public static List<TestOrderRees> orderRees(){
        List<TestOrderRees> testOrderRees = new ArrayList<>();
        TestOrderRees orderRees = new TestOrderRees();
        orderRees.setGoodsId(1001);
        orderRees.setName("苹果手机");
        orderRees.setNumber(1);
        testOrderRees.add(orderRees);
        orderRees = new TestOrderRees();
        orderRees.setGoodsId(1002);
        orderRees.setName("华为手机");
        orderRees.setNumber(2);
        testOrderRees.add(orderRees);
        orderRees = new TestOrderRees();
        orderRees.setGoodsId(1003);
        orderRees.setName("小米手机");
        orderRees.setNumber(1);
        testOrderRees.add(orderRees);
        orderRees = new TestOrderRees();
        orderRees.setGoodsId(1004);
        orderRees.setName("天音手机");
        orderRees.setNumber(3);
        testOrderRees.add(orderRees);
        orderRees = new TestOrderRees();
        orderRees.setGoodsId(1002);
        orderRees.setName("华为手机");
        orderRees.setNumber(1);
        testOrderRees.add(orderRees);
        return testOrderRees;
    }

2.去重



List<TestOrderRees> testOrderRees = orderRees();
        // 去重
        List<TestOrderRees> result = testOrderRees.stream()
                .collect(Collectors.collectingAndThen(Collectors.toCollection(() ->
                        new TreeSet<>(Comparator.comparing(TestOrderRees::getGoodsId))),
                        ArrayList::new));
        System.out.println(result.toString());
        // [TestOrderRees(goodsId=1001, name=苹果手机, number=1),
        // TestOrderRees(goodsId=1002, name=华为手机, number=2),
        // TestOrderRees(goodsId=1003, name=小米手机, number=1),
        // TestOrderRees(goodsId=1004, name=天音手机, number=3)]

3.排序 升序 sort 降序 sorted



List<TestOrderRees> testOrderRees = orderRees();
        // 排序 降序 reversed()   升序 去掉reversed()
        List<TestOrderRees> result = testOrderRees.stream().sorted(Comparator.comparing(
                TestOrderRees::getGoodsId).reversed()).collect(Collectors.toList());
        System.out.println(result);
        //[TestOrderRees(goodsId=1004, name=天音手机, number=3),
        // TestOrderRees(goodsId=1003, name=小米手机, number=1),
        // TestOrderRees(goodsId=1002, name=华为手机, number=2),
        // TestOrderRees(goodsId=1002, name=华为手机, number=1),
        // TestOrderRees(goodsId=1001, name=苹果手机, number=1)]

4.分组计数



List<TestOrderRees> testOrderRees = orderRees();
        // 分组计数
        Map<Integer, Long> result = testOrderRees.stream().collect(
                Collectors.groupingBy(TestOrderRees::getGoodsId, Collectors.counting()));
        System.out.println(result);
        // {1001=1, 1002=2, 1003=1, 1004=1}

5.上面的函数都可以用到一起的 可以自己试试结合其他函数,比如这个是 排序再分组 求出每组的总数量





List<TestOrderRees> testOrderRees = orderRees();
// 上面的函数都可以用到一起的  可以自己试试结合其他函数,比如这个是  排序再分组 求出每组的总数量
Map<Integer, Long> result = testOrderRees.stream().sorted(Comparator.comparing(
        TestOrderRees::getGoodsId).reversed()).collect(
            Collectors.groupingBy(TestOrderRees::getGoodsId,Collectors.counting()));
System.out.println(result);
// {1001=1, 1002=2, 1003=1, 1004=1}



6.根据单个字段分组  求出每组某个字段值的总和


List<TestOrderRees> testOrderRees = orderRees();
// 根据单个字段分组  求出每组某个字段值的总和
Map<Integer, Integer> result = testOrderRees.stream()
        .collect(Collectors.groupingBy(TestOrderRees::getGoodsId,
                Collectors.summingInt(TestOrderRees::getNumber)));
System.out.println(result);
// {1001=1, 1002=3, 1003=1, 1004=3}

7.多字段分组  在groupingBy里面计算总数 对数据不友好 我暂时试过是带不出去的 



List<TestOrderRees> testOrderRees = orderRees();
        List<TestOrderRees> orderRees = new ArrayList<>();
        // 多字段分组 对数据不友好 我暂时试过是带不出去的
        testOrderRees.stream()
                .collect(Collectors
                        .groupingBy(
//                                TestOrderRees::getGoodsId,
                                order -> new TestOrderRees(order.getGoodsId()),
//                                order -> new TestOrderRees(order.getGoodsId(), order.getName()),
                                Collectors.summarizingLong(TestOrderRees::getNumber)
                        )
                )
                .forEach((k,v) -> {
                    k.setNumber((int) v.getSum());
                    orderRees.add(k);
                });
        System.out.println(orderRees.toString());
        // [TestOrderRees(goodsId=1001, name=null, number=1),
        // TestOrderRees(goodsId=1003, name=null, number=1),
        // TestOrderRees(goodsId=1002, name=null, number=3),
        // TestOrderRees(goodsId=1004, name=null, number=3)]

8.单字段 多字段分组 再计算某个值得总数 这个比较友好 可以根据map再重新带出原本得参数,在groupingBy外面map时计算总数 



List<TestOrderRees> testOrderRees = orderRees();
        List<TestOrderRees> result = testOrderRees.stream()
                // 根据goodsId进行分组 单字段  多字段
                .collect(Collectors.groupingBy(
                        // 第一种 单字段
//                        TestOrderRees::getGoodsId
                        // 第二种 new出实例 单字段
                        order -> new TestOrderRees(order.getGoodsId())
                        // 第三种 new出实例 多字段
//                        order -> new TestOrderRees(order.getGoodsId(), order.getName())
                ))
                .entrySet()
                .stream()
                .map(entry -> {

//                    Integer key = entry.getKey();

                    // new 实例分组时
                    TestOrderRees key = entry.getKey();

                    // 分好的组
                    List<TestOrderRees> value = entry.getValue();
                    // 根据该组 算出总数
                    Integer sum = value.stream().mapToInt(TestOrderRees::getNumber).sum();
                    // 放入数据
                    TestOrderRees rees = new TestOrderRees();
//                    rees.setGoodsId(key);
                    // new 实例分组时
                    rees.setGoodsId(key.getGoodsId());

                    rees.setNumber(sum);
                    rees.setName(value.get(0).getName());
                    return rees;
                })
                // 根据goodsId降序排序
                .sorted(Comparator.comparing(TestOrderRees::getGoodsId).reversed())
                .collect(Collectors.toList());
        System.out.println(result);
        // [TestOrderRees(goodsId=1004, name=天音手机, number=3),
        // TestOrderRees(goodsId=1003, name=小米手机, number=1),
        // TestOrderRees(goodsId=1002, name=华为手机, number=3),
        // TestOrderRees(goodsId=1001, name=苹果手机, number=1)]

  • 5
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果要对一个 `List` 中的对象进行去重,可以使用 Java 8 中的 `stream` 和 `distinct` 方法。假设我们有一个 `Person` 类,其中包含 `name` 和 `age` 两个字段,我们要对一个 `List<Person>` 进行去重,可以按照以下方法进行。 ```java List<Person> personList = new ArrayList<>(); personList.add(new Person("Alice", 20)); personList.add(new Person("Bob", 30)); personList.add(new Person("Alice", 20)); personList.add(new Person("Charlie", 40)); List<Person> distinctPersonList = personList.stream() .distinct() .collect(Collectors.toList()); ``` 这里我们使用 `distinct` 方法对 `stream` 中的元素进行去重操作,`distinct` 方法默认使用对象的 `equals` 方法进行判断是否相等,如果要自定义对象的相等规则,可以重写 `equals` 方法和 `hashCode` 方法。 我们可以在 `Person` 类中重写 `equals` 方法和 `hashCode` 方法,按照 `name` 和 `age` 两个字段进行判断是否相等。 ```java public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return age == person.age && Objects.equals(name, person.name); } @Override public int hashCode() { return Objects.hash(name, age); } } ``` 使用重写后的 `equals` 方法和 `hashCode` 方法,我们可以对 `Person` 对象进行按照 `name` 和 `age` 两个字段进行去重。 ```java List<Person> distinctPersonList = personList.stream() .distinct() .collect(Collectors.toList()); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值