List 如何根据对象的属性去重?Java 8 轻松搞定!

点击上方“Java基基”,选择“设为星标”

做积极的人,而不是积极废人!

每天 14:00 更新文章,每天掉亿点点头发...

源码精品专栏

 

来源:blog.csdn.net/jiaobuchong/

article/details/54412094/


一、去除List中重复的String

public List<String> removeStringListDupli(List<String> stringList) {
    Set<String> set = new LinkedHashSet<>();
    set.addAll(stringList);

    stringList.clear();

    stringList.addAll(set);
    return stringList;
}

或使用Java8的写法:

List<String> unique = list.stream().distinct().collect(Collectors.toList());

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能。

项目地址:https://github.com/YunaiV/ruoyi-vue-pro

二、List中对象去重

比如现在有一个 Person类:

public class Person {
    private Long id;

    private String name;

    public Person(Long id, String name) {
        this.id = id;
        this.name = name;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

重写Person对象的equals()方法和hashCode()方法:

@Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Person person = (Person) o;

        if (!id.equals(person.id)) return false;
        return name.equals(person.name);

    }

    @Override
    public int hashCode() {
        int result = id.hashCode();
        result = 31 * result + name.hashCode();
        return result;
    }

下面对象去重的代码:

Person p1 = new Person(1l, "jack");
        Person p2 = new Person(3l, "jack chou");
        Person p3 = new Person(2l, "tom");
        Person p4 = new Person(4l, "hanson");
        Person p5 = new Person(5l, "胶布虫");

        List<Person> persons = Arrays.asList(p1, p2, p3, p4, p5, p5, p1, p2, p2);

        List<Person> personList = new ArrayList<>();
        // 去重
        persons.stream().forEach(
                p -> {
                    if (!personList.contains(p)) {
                        personList.add(p);
                    }
                }
        );
        System.out.println(personList);

List 的contains()方法底层实现使用对象的equals方法去比较的,其实重写equals()就好,但重写了equals最好将hashCode也重写了。

可以参见:

  • http://stackoverflow.com/questions/30745048/how-to-remove-duplicate-objects-from-java-arraylist

  • http://blog.csdn.net/growing_tree/article/details/46622579

基于微服务的思想,构建在 B2C 电商场景下的项目实战。核心技术栈,是 Spring Boot + Dubbo 。未来,会重构成 Spring Cloud Alibaba 。

项目地址:https://github.com/YunaiV/onemall

三、根据对象的属性去重

下面要根据Person对象的id去重,那该怎么做呢?

写一个方法吧:

public static List<Person> removeDupliById(List<Person> persons) {
        Set<Person> personSet = new TreeSet<>((o1, o2) -> o1.getId().compareTo(o2.getId()));
        personSet.addAll(persons);

        return new ArrayList<>(personSet);
    }

通过Comparator比较器,比较对象属性,相同就返回0,达到过滤的目的。

再来看比较炫酷的Java8写法:

import static java.util.Comparator.comparingLong;
import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.toCollection;

// 根据id去重
     List<Person> unique = persons.stream().collect(
                collectingAndThen(
                        toCollection(() -> new TreeSet<>(comparingLong(Person::getId))), ArrayList::new)
        );

这段炫酷的代码是google的,还不明白是怎么个原理,等我好好研究一下,再专门写篇文章好好阐述一下。

还有一种写法:

public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
        Map<Object, Boolean> map = new ConcurrentHashMap<>();
        return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }

// remove duplicate
        persons.stream().filter(distinctByKey(p -> p.getId())).forEach(p -> System.out.println(p));

java8 确实简化了很多冗长的操作,精简了代码,小伙,研究java8去吧!



欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢

ee91c3dbf631b113f31d9d82df220af3.png

已在知识星球更新源码解析如下:

a11adc2dc3eeb3e85fb02de1b1a6a126.png

f737c4a6d859581436115f0da9b10d42.png

055589caf8a3a214bac61dc5e971fe91.png

c2447ef2a5d3ceee455348717419f51f.png

最近更新《芋道 SpringBoot 2.X 入门》系列,已经 101 余篇,覆盖了 MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。

提供近 3W 行代码的 SpringBoot 示例,以及超 6W 行代码的电商微服务项目。

获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。

文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在Java 8中,我们可以使用Stream API和Lambda表达式来根据list对象属性去重。下面是具体步骤: 1. 通过Stream API将list对象转换成Stream流; 2. 使用distinct()方法根据对象属性去重,该方法使用对象的equals()方法判断是否相等; 3. 如果对象类没有重写equals()方法,则需要在该类中重写该方法,以保证根据对象属性去重的正确性; 4. 最后,使用collect()方法将Stream流转换回list对象。 以下是示例代码: ``` // 定义Person类 public class Person { private String name; private int age; // 构造方法和getter/setter方法省略 @Override public boolean equals(Object obj) { // 重写equals()方法 if (obj == this) { return true; } if (!(obj instanceof Person)) { return false; } Person person = (Person) obj; return this.name.equals(person.getName()) && this.age == person.getAge(); } } // 定义list对象 List<Person> personList = Arrays.asList( new Person("Alice", 20), new Person("Bob", 25), new Person("Alice", 20), new Person("Charlie", 30) ); // 根据名称和年龄属性去重 List<Person> distinctPersonList = personList.stream().distinct().collect(Collectors.toList()); ``` 以上代码将根据Person对象的name和age属性去重,最终输出的distinctPersonList为: ``` [Person{name='Alice', age=20}, Person{name='Bob', age=25}, Person{name='Charlie', age=30}] ``` ### 回答2: 在Java 8中,可以使用stream()和distinct()方法对List对象属性进行去重。 首先,我们需要创建一个包含对象List,例如: ``` List<Person> personList = new ArrayList<>(); personList.add(new Person("Alice", 20)); personList.add(new Person("Bob", 20)); personList.add(new Person("Alice", 25)); ``` 其中,每个Person对象包含两个属性,分别为name和age。我们现在需要根据name属性去重。 我们可以使用以下代码实现: ``` List<Person> distinctList = personList.stream() .filter(distinctByKey(Person::getName)) .collect(Collectors.toList()); public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) { Map<Object, Boolean> seen = new ConcurrentHashMap<>(); return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null; } ``` 以上代码中,我们首先对personList使用stream()方法,然后使用filter()方法筛选出根据Person对象的name属性去重后的数据。在filter()方法中,使用distinctByKey()方法从而实现去重。该方法使用了Java 8中的ConcurrentHashMap进行操作,首先根据keyExtractor将name属性作为key,将Boolean.TRUE作为value存入ConcurrentHashMap中,如果putIfAbsent()方法返回null,表示当前元素还未放入ConcurrentHashMap,即为不重复元素,否则返回已存在的元素,即为重复元素。 最后,使用collect()方法将去重后的元素存入distinctList中。我们可以通过打印distinctList的元素数量进行验证去重是否成功。 该方法可以灵活地根据各种属性进行去重,只需更改keyExtractor即可。 ### 回答3: Java 8 提供了非常便捷、高效的方式根据 list 对象属性去重,主要借助 lambda 表达式和 Stream API 实现。下面讲解具体实现步骤: 1. 定义一个类,作为 list 的元素,并在该类中定义需要去重属性: ``` public class Person { private int id; private String name; //......getters and setters省略 } ``` 2. 创建一个 list,添加元素: ``` List<Person> list = new ArrayList<>(); list.add(new Person(1, "Tom")); list.add(new Person(2, "Jerry")); list.add(new Person(1, "Tom")); list.add(new Person(3, "Lucy")); ``` 此时,list 中包含 4 个元素,其中第 1 个和第 3 个元素 id 属性相同,需要去重。 3. 使用 Stream API 和 lambda 表达式去重: ``` List<Person> distinctList = list.stream() .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Person::getId))), ArrayList::new)); ``` 解释一下上述代码的实现思路:首先用 `.stream()` 将 list 转换成 Stream,然后用 `Collectors.collectingAndThen()` 把 Collector 转换成了另一个 Collector,这里直接使用了 `Collectors.toCollection()` 把结果转成 TreeSet(TreeSet 是有序的 Set),并使用 Comparator.comparing 对元素进行比较,根据 id 属性进行去重。 最后,再把结果转换成 ArrayList 即可。 4. 打印去重后的结果: ``` for (Person person : distinctList) { System.out.println(person.getId() + " " + person.getName()); } ``` 此时输出结果如下: ``` 1 Tom 2 Jerry 3 Lucy ``` 由于已经按 id 属性去重,所以输出结果不再包含重复元素。 总结来说,Java 8 根据 list 对象属性去重比较简单,同样的方法也适用于其他属性去重,只需要将 `Comparator.comparing()` 的参数修改为其他属性即可。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值