`

list去重

    博客分类:
  • list
 
阅读更多

List数据去重在开发中是十分常见的场景,下面为大家介绍一个简单的方法:利用Set去重,但根据存储元素的不同,可以分为以下两类:

 

1. List中存储的是基本数据类型

下面看一段示例代码:

public class Test {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c", "d", "a", "b"));
        System.out.println(list);// 输出结果:[a, b, c, d, a, b]
        Set<String> set = new HashSet<>(list);
        List<String> newList = new ArrayList<>(set);
        System.out.println(newList);// 输出结果:[a, b, c, d]
    }
}
————————————————
原文链接:https://blog.csdn.net/weixin_40328662/article/details/99843102

 

 

2. List中存储的是对象类型

示例代码:

 

public class Test {
    public static void main(String[] args) {
        List<People> peopleList = new ArrayList<>();
        peopleList.add(new People("Joey", "001"));
        peopleList.add(new People("Joey", "001"));
        peopleList.add(new People("Johnny", "002"));
        peopleList.add(new People("Route", "003"));
        peopleList.add(new People("Vans", "004"));
        Set<People> peopleSet = new HashSet<>(peopleList);
        System.out.println(peopleSet);
    }
}
 
public class People {
 
    private String name;
    private String addrNum;
 
    // 省略无参、有参构造器,get、set方法,toString方法
 
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null || this.getClass() != obj.getClass()) {
            return false;
        }
        People people = (People) obj;
        return Objects.equals(name, people.name)
                && Objects.equals(addrNum, people.addrNum);
    }
 
    @Override
    public int hashCode() {
        return Objects.hash(name, addrNum);
    }
}
————————————————

原文链接:https://blog.csdn.net/weixin_40328662/article/details/99843102

 

 

如果List中存储的是对象类型,要想利用Set去重,就必须重写存储对象的equals()和hashCode()方法,为什么呢?

 

原因其实很简单,如下所示,HashSet的实现其实是HashMap,而HashMap中,通过key区分不同元素,key的比较顺序第一步就是计算对象的hashCode,看是否存在,第二步查找对应hashCode位置的对象是否与当前对象相等。这就需要用到hashCode()与equals()方法,equals()方法的默认实现是 ==,对于对象而言,比较的是内存中的地址。上述示例中,其实我们想要的效果是name与addrNum相等即视为同一个对象,但new的操作在堆中都是开辟新的内存空间,故两个对象的地址不一致,所以,我们必须覆写这两个方法

 

/**

 * Constructs a new, empty set; the backing <tt>HashMap</tt> instance has

 * default initial capacity (16) and load factor (0.75).

 */

public HashSet() {

    map = new HashMap<>();

}

 

/**

 * Object类中equlas的默认实现

 */

public boolean equals(Object obj) {

    return (this == obj);

}

 

是不是非常简单,但可能有朋友会问,String并不属于基本数据类型,为什么也可以直接利用Set去重?其实,String类也重写了equals()和hashCode()方法,感兴趣的朋友可以去查看相关源码

 

总结:

利用HashSet去重,本质是利用了HashMap去重原理,Map/Set的key为自定义对象时,必须重写hashCode和equals

 

遵循如下规则(来自阿里巴巴Java开发手册):

 

1. 只要重写equals,就必须重写hashCode

 

2. 因为set存储的是不重复的对象,依据hashCode和equals进行判断,所以set存储的对象必须重写这两个方法

 

3. 如果自定义对象作为Map的键,那么必须重写hashCode和equals

————————————————

原文链接:https://blog.csdn.net/weixin_40328662/article/details/99843102

 

 

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics