HashSet保存自定义不重复对象

来源:互联网 发布:音乐推荐算法 lr gbdt 编辑:程序博客网 时间:2024/05/30 23:53

前言

首先要了解HashSet实现的机制,如果不了解,对于下面的操作也是一直半解,用过一次就忘,并没有什么意义。

HashSet实现原理

HashSet的实现内部其实是一个HashMap,HashMap的实现就是根据key来进行Hash变换映射到index下,如果index相同,会根据equal来判断key是不是相同,不相同就在这个index使用链表存储,key相同就覆盖原来的值。这样就保证了key的唯一性。HashSet就是利用HashMap key的唯一性来实现集合内的数据不重复。这就是HashSet的原理了。

对象和字符串的不同

根据上面的HashSet的实现原理,Set里面的元素都是HashMap的Key,而在HashMap中,Key默认使用的是字符串,为什么不使用对象呢?是因为在HashMap中判断Key是否相等的关键在于equal,Object默认的equal实现是使用==来判断两个对象是否相等的,这样就会导致String和普通的Object有很大的不同。String可以使用==来判断两个字符串是否相等,但是对于普通对象来说==只是判断对象的引用是否相等。这样一来,目标就很明确了,要保存自定义的不重复对象,必须要重写对象的equal方法。

规约

再根据一条很有意义的规约:

重写equal方法必须要重写hashCode方法。

这样就知道我们需要做什么了:重写equal方法和hashCode方法。

示例

下面例子指定一个属性,自定义具有相同该属性的对象只能存储一次,实现了不重复存储。也就是去重。

package hashSetExample;import java.util.HashSet;import java.util.Set;/** * Created by liusxg on 2017/3/9. */public class RemoveDuplicateObj {    static class Test {        private String name;        private Integer age;        public String getName() {            return name;        }        public void setName(String name) {            this.name = name;        }        public Integer getAge() {            return age;        }        public void setAge(Integer age) {            this.age = age;        }        //重写equal        @Override        public boolean equals(Object var1) {            if (!(var1 instanceof Test)) {                return false;            }            Test testVal1 = (Test) var1;            if (testVal1.name == null) {                return false;            }            return this.name == testVal1.getName();        }        //重写hashCode        @Override        public int hashCode() {            return this.name.hashCode();        }        //重写toString,为打印方便        @Override        public String toString() {            return "{"+this.name+","+this.getAge()+"}";        }    }    public static void main(String[] args) {        //测试数据        Test test1 = new Test();        test1.setName("小明");        test1.setAge(10);        Test test2 = new Test();        test2.setName("小红");        test2.setAge(20);        Test test3 = new Test();        test3.setName("小明");        test3.setAge(30);        //测试代码        Set<Test> testSet = new HashSet<Test>();        testSet.add(test1);        testSet.add(test2);        testSet.add(test3);        System.out.println(testSet.size());        System.out.println(testSet.toString());    }}

输出结果:
2
[{小明,10}, {小红,20}]

如果把equal和hashCode重写注释掉,输出结果为:
3
[{小红,20}, {小明,10}, {小明,30}]

0 0
原创粉丝点击