快速去重:使用Java根据对象某一属性去除重复对象的实现指南

 一、导言

Java中的对象去重操作?跟着小编一起学习吧!

在处理对象集合时,有时候我们需要根据对象的某个属性进行去重操作。Java给我们提供了多种方法来实现这个功能。今天,小编就来给大家介绍一下如何使用Java根据对象的某个属性进行去重操作。

方案一:使用自定义equals()和hashCode()方法

I.原理讲解

  • 提供一个自定义的类,包含需要去重的属性。
  • 重写equals()方法,比较对象的name属性是否相等。
  • 重写hashCode()方法,根据属性生成哈希码。
  • 使用HashSet或LinkedHashSet进行去重操作。

II. 代码示例

// 重新equals和hashCode方法
public class Person {

    public String name;
    public Integer age;
    public Sex sex;
    
   
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name);
    }

    ······
}

public class ObjectDistinctTest {

    public Person[] peoples;

    public List personList;

    // 构建数据源
    @Before
    public void before() {
        Person person = new Chinese("大白", 21, Sex.man);
        Person person1 = new Chinese("小兰", 25, Sex.woman);
        Person person2 = new Chinese("小红", 23, Sex.woman);
        Person person3 = new Chinese("小赵", 20, Sex.man);
        Person person4 = new Chinese("小青", 18, Sex.woman);
        Person person5 = new Chinese("小赵", 17, Sex.man);
        Person person6 = new Chinese("小麻", 50, Sex.man);
        this.peoples =new Person[]{ person, person1, person2, person3, person4, person5, person6};
        this.personList = Arrays.asList(peoples);
    }

    /**
     * 使用自定义equals()和hashCode()方法
     */
    @Test
    public void testCase01() {

        // 需求:根据Person对象的name属性进行去重,name属性相同,则视为重复元素
        // 存入顺序和取出顺序不一致
        Set distinctPersonSet = new HashSet<>();

        for (Person person : personList) {
            distinctPersonSet.add(person); //
        }

        List distinctPersonList = new ArrayList<>(distinctPersonSet);
        distinctPersonList.forEach(System.out::println); // 打印去重后的数据
    }

    /**
     * 使用自定义equals()和hashCode()方法
     */
    @Test
    public void testCase02() {
        // 或使用 LinkedHashSet 保持插入顺序
        Set distinctPersonSet = new LinkedHashSet<>();

        for (Person person : personList) {
            distinctPersonSet.add(person);
        }

        List distinctPersonList = new ArrayList<>(distinctPersonSet);
        distinctPersonList.forEach(System.out::println); // 打印去重后的数据
    }
}



方案二:使用循环和集合

I.原理讲解

  • 创建了一个新的集合来存储去重后的对象
  • 遍历集合列表
  • 判断对象属性是否重复
  • 去除重复对象

II. 代码示例

public class ObjectDistinctTest {

    public Person[] peoples;

    public List personList;

    // 构建数据源
    @Before
    public void before() {
        Person person = new Chinese("大白", 21, Sex.man);
        Person person1 = new Chinese("小兰", 25, Sex.woman);
        Person person2 = new Chinese("小红", 23, Sex.woman);
        Person person3 = new Chinese("小赵", 20, Sex.man);
        Person person4 = new Chinese("小青", 18, Sex.woman);
        Person person5 = new Chinese("小赵", 17, Sex.man);
        Person person6 = new Chinese("小麻", 50, Sex.man);
        this.peoples =new Person[]{ person, person1, person2, person3, person4, person5, person6};
        this.personList = Arrays.asList(peoples);
    }

    @Test
    public void testCase() {
        // 此方式无需实现equals方法
        List newList = new ArrayList<>();
        for (Person person: this.personList
        ) {
            if (newList.stream().noneMatch(x -> x.getName().equals(person.getName()))) { // 判断新集合中是否包含此对象,不包含才能加入到新集合中
                newList.add(person);
            }
        }
        List distinctList = newList.stream().sorted(Comparator.comparing(Person::getAge)).collect(Collectors.toList());
        distinctList.forEach(System.out::println);
    }

}

方案三:使用自定义equals()和Java 8中的distinct方法

I.原理讲解

  • 提供一个自定义的类,包含需要去重的属性。
  • 重写equals()方法,比较对象的name属性是否相等。
  • 重写hashCode()方法,根据属性生成哈希码。
  • 使用Java 8Stream API中的distinct方法进行去重操作

II. 代码示例

// 重新equals和hashCode方法
public class Person {

    public String name;
    public Integer age;
    public Sex sex;
    
   
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name);
    }

    ······
}

public class ObjectDistinctTest {

    public Person[] peoples;

    public List personList;

    // 构建数据源
    @Before
    public void before() {
        Person person = new Chinese("大白", 21, Sex.man);
        Person person1 = new Chinese("小兰", 25, Sex.woman);
        Person person2 = new Chinese("小红", 23, Sex.woman);
        Person person3 = new Chinese("小赵", 20, Sex.man);
        Person person4 = new Chinese("小青", 18, Sex.woman);
        Person person5 = new Chinese("小赵", 17, Sex.man);
        Person person6 = new Chinese("小麻", 50, Sex.man);
        this.peoples =new Person[]{ person, person1, person2, person3, person4, person5, person6};
        this.personList = Arrays.asList(peoples);
    }

    /**
     * 使用自定义equals()和Stream API中的distinct方法实现元素的去重
     */
    @Test
    public void testCase01() {

        // 需求:根据Person对象的name属性进行去重,name属性相同,则视为重复元素
           this.personList.stream()    // 获取流对象
                .distinct()         // 去除重复元素
                .collect(Collectors.toList())   // 收集为List集合
                .forEach(System.out::println);  // 打印去重后的元素
    }
}



方案四:将List以name属性为key转换为Map

I.原理讲解

  • 使用Stream API中的终结方法collect
  • 将List转为Map,key为Person类中的name属性,value为Person对象
  • 获取使用values方法,获取Map中的value,即为去重后的List

II. 代码示例

public class ObjectDistinctTest {

    public Person[] peoples;

    public List personList;

    // 构建数据源
    @Before
    public void before() {
        Person person = new Chinese("大白", 21, Sex.man);
        Person person1 = new Chinese("小兰", 25, Sex.woman);
        Person person2 = new Chinese("小红", 23, Sex.woman);
        Person person3 = new Chinese("小赵", 20, Sex.man);
        Person person4 = new Chinese("小青", 18, Sex.woman);
        Person person5 = new Chinese("小赵", 17, Sex.man);
        Person person6 = new Chinese("小麻", 50, Sex.man);
        this.peoples =new Person[]{ person, person1, person2, person3, person4, person5, person6};
        this.personList = Arrays.asList(peoples);
    }

   
    @Test
    public void testCase03() {
        this.personList.stream() // 获取流对象
                .collect(Collectors.toMap(Person::getName, y -> y,(s, a) -> s))// 将List根据Person类中的name属性收集为Map,key为name,value为Person对象,当后面对象name属性跟前者相同时,使用前者。
                .values()    // 获取Map中的key
                .stream()
                .collect(Collectors.toList())
                .forEach(System.out::println);
    }
}

五、总结

想象一下,现在你可以轻松地根据对象的某一属性去除重复对象了!

不仅如此,这个技巧还可以应用在各种不同的场景中,让你的代码更加简洁高效!

不管是初学者还是资深开发者,都会对这个技巧爱不释手!快来试试吧!

你可能感兴趣的:(java,开发语言,后端,eclipse,intellij-idea)