JAVA8 - 使用stream api进行list集合指定字段去重

本文介绍了一种在Java8中使用collectingAndThen方法结合TreeSet进行去重的技巧,具体示例展示了如何根据实体类中的姓名和年龄字段去除重复记录。

背景

有一个list,实体包含多个字段,当其中两个字段值均相同时,就认为list中的这两条记录是一样的

去重

java8中有一个collectingAndThen可以根据多个字段去重

依据姓名和年龄去重,当姓名和年龄相同时,认为这两个实体相同


class FlightTicketInfo {

    private String orderNumber;

    private String userName;

    private String age;

    public FlightTicketInfo(String orderNumber, String userName, String age) {
        this.orderNumber = orderNumber;
        this.userName = userName;
        this.age = age;
    }

    @Override
    public String toString() {
        return "FlightTicketInfo{" +
                "orderNumber='" + orderNumber + '\'' +
                ", userName='" + userName + '\'' +
                ", age='" + age + '\'' +
                '}';
    }

    public String getOrderNumber() {
        return orderNumber;
    }

    public String getUserName() {
        return userName;
    }

    public String getAge() {
        return age;
    }
}

    @Test
    public void testList(){
        List<FlightTicketInfo> infoList = new ArrayList<>();
        infoList.add(new FlightTicketInfo("11111", "xiaoming", "22"));
        infoList.add(new FlightTicketInfo("22222", "xiaoming", "22"));
        infoList.add(new FlightTicketInfo("33333", "xiaoming", "23"));
        infoList.add(new FlightTicketInfo("11111", "xiaoming", "22"));
        infoList.stream()
                .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(f -> f.getUserName()+f.getAge()))), ArrayList::new))
                .forEach(System.out::println);
    }
Java中处理集合时,我们常常需要对元素按照特定字段进行,并且有时还需要统计某些字段的信息。这里以`List<YourClass>`为例来进行说明。 ### 操作 假设有一个包含多个对象的列表 `List<Person> personList`, 其中每个Person有两个属性分别是name和age, 现在我想要根据名字(name)来复项: ```java import java.util.*; import java.util.stream.Collectors; public class Example { static class Person{ private String name; private int age; // 构造函数、getter/setter等 @Override public boolean equals(Object o){ if (this == o) return true; if (!(o instanceof Person)) return false; Person person = (Person)o; return Objects.equals(this.name, person.name); } @Override public int hashCode(){ return Objects.hash(name); } } public static void main(String[] args) { List<Person> persons = Arrays.asList( new Person("张三", 20), new Person("李四", 24), new Person("王五", 35), new Person("张三", 28) ); Set<Person> uniquePersonsByName = persons.stream() .collect(Collectors.toMap(p -> p.getName(), Function.identity(), (existing, replacement) -> existing)) .values().stream() .collect(Collectors.toSet()); System.out.println(uniquePersonsByName); } } ``` 上面代码通过覆写equals()及hashCode()保证了当两个person拥有相同的姓名时会被认为相等;之后再借助Stream API结合Collectors工具类完成工作。 对于计算指定字段值如求年龄总和,则可以在上述基础上继续加工: ```java int sumOfAge = uniquePersonsByName.stream() .mapToInt(Person::getAge).sum(); System.out.println(sumOfAge); ``` 这将打印出所有唯一人员(按名称区分)的年龄之和。 另外还可以使用groupingBy收集器做更复杂的数据分析任务。 希望这个例子对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值