• hashSet中的equals方法和hashCode方法


    1.

     //2. 验证唯一性,存入自定义元素  
    class Person{  
        private String name;  
        private int age;  
         
        public static void sop(Object o){  
            System.out.println(o);  
        }  
       
        public Person(String name, int age){  
            this.name =name;  
            this.age =age;  
        }  
       
        public void setName(String name){  
            this.name =name;  
        }  
         
        public String getName(){  
            return this.name;  
        }  
       
        public void setAge(int age){  
            this.age =age;  
        }  
       
        public int getAge(){  
            return this.age;  
        }  
       
        public String toString(){  
            return this.name+"::"+this.age;  
        }  
    }  

    测试代码:

     class HashSetDemoIII  
    {  
        public static void sop(Object o){  
            System.out.println(o);  
        }  
       
        public static void main(String[] args){  
            HashSeths =new HashSet();  
            hs.add(new Person("a1", 11));  
            hs.add(new Person("a2", 12));  
            hs.add(new Person("a3", 13));  
            hs.add(new Person("a2", 12));  
       
            Iteratorit =hs.iterator();  
            while(it.hasNext()){  
                sop(it.next());  
            }  
        }  
    } 

    测试结果:

    【结论】循环迭代结果:a2::12打印了两次,说明重复的元素new Person("a2", 12)被添加到集合中去。没有保证HashSet的唯一性。

    2.为Person类重写equals()方法判定两个对象的内容是否一致

     public boolean equals(Object obj){  
    if(!(obj instanceof Person)){  
            return false;  
        }  
         
        Personp =(Person)obj;  
       
        //用来查看equals方法是否被调用  
        sop(this.name +".......equals......."+ p.name);  
        //认为名字相同并且年龄一样大的两个对象是一个  
    return this.name.equals(p.name) && this.age == p.age;  
    }  

    测试结果:

    【结论】循环迭代结果:a2::12被打印了两次,说明重复的元素new Person("a2", 12)被添加到集合中去。没有保证HashSet的唯一性。

    同时equals没有被调用,说明仅仅重写equals方法没起到作用

     

    【分析】HashSet在存储元素的时候,是先查看两个对象的哈希值是否一样的。

    如果哈希值一样再调用元素对象的equals方法,查看两个对象的内容是否一样。

    {1}. 如果equlas比较的值一样,说明两个对象相同能添加到HashSet对应的集合中。

    {2}. 如果equlas比较的值不一样,说明两个对象不同可以添加到HashSet对应的集合中

    如果哈希值不一样,直接认为两个对象不一样,equals方法不起作用

    【本例分析】这个例子中,由于四个Person类的对象都是new出来的,所以没有重写的hashCode是调用本地方法产生的值,所以一定是四个不相同的hashCode值。hashCode值都不一样,equals方法不起作用。

    3.重写HashCode方法

    为避免内容重复的数据添加到HashSet集合中,就必须重写hashCode()方法。

    [1]. hashCode的返回值设置数值:

    示例代码:

      1. public int hashCode(){  
      2.     sop(this.name +"......hashCode");  
      3.     return this.name.hashCode() + 29*age;  

    这种做法,同样可以避免HashSet集合中不会存入相同元素。

    【两种方式的具体区别和详细过程见个人总结。】

    (4). 重写hashCode和equals的时候,常犯的错误

    [1]. 子类重写hashCode的时候,将方法名写错,写成hasCode

    [2]. 子类重写equals的时候,将参数传错,本来应该是public boolean equals(Object obj){}却写成了public boolean equals(自定义类型自定义类型引用)。这样集合框架的底层不会调用这个重载的方法。

    2.    HashSet总结

    1). HashCode如何保证元素唯一性?

    (1). 需要重写的方法

    通过重写自定义类hashCode()equals( )两个方法来达到元素的唯一性保证。

    (2). 方法重写之后,执行的顺序

    [1]. 如果元素hashCode值相同,才会使用equals()方法进行判断。

    [2]. 如果元素hashCode值不同不会调用equals()方法

    2). 开发中的建议

    (1). 自定义对象,一定要重写hashCode和equals两个方法

           如果不重写,则默认的本地方法hashCode【OS来产生】会产生值都不一样的hashCode,即使内容重复的元素会被添加到HashSet中,无法保证元素的唯一性

    【注意】开发中重写这两个方法,方便集合框架的底层调用这些方法。

    (2). 建立高效的hashCode会使得hashSet添加元素的过程更为高效。

           hashCode的值不同,则调用equals()方法比较的环节便可以省去。

    3). HashSet判断和删除元素的依据

    示例代码:

     

    public class HashSetDemoIV {  
        public static void main(String[] args) {  
            HashSeths =new HashSet();  
            hs.add(new Person("a1", 11));  
            hs.add(new Person("a2", 12));  
            hs.add(new Person("a3", 13));  
            System.out.println("hashSet中的元素:"+ hs);  
             
            System.out.println("************************");  
            System.out.println("HashSet的 contains依据:"+ hs.contains(new Person("a1", 11)));  
             
            System.out.println("************************");  
            System.out.println("HashSet的 remove依据:"+ hs.remove(new Person("a3", 13)));  
            System.out.println("************************");  
            System.out.println("hashSet中的元素:"+ hs);  
        }  
    } 

    打印结果:

    可以看出,hashSet在删除和判断元素的时候,依据的仍然是hashCode和equals这两个方法。

    结论:

    [1]. HashSet判断删除添加元素等操作依据的是被操作元素所在的类的hashCode()equals( )这两个方法。

    [2]. ArrayList做同等的操作,依据的仅仅是equals( )方法

  • 相关阅读:
    【MVC 1】MVC+EF实体框架—原理解析
    数据结构导论(一)
    【JavaScript 14—学习总结】:从小事做起
    【JavaScript 13—应用总结】:锁屏遮罩
    【JavaScript 12—应用总结】:弹出登录框
    【JavaScript 11—应用总结】:下拉菜单
    【JavaScript 10—应用总结】:连缀
    【EF 1】EF实体框架 原理+实例
    【多 线 程】
    【命 令 行】
  • 原文地址:https://www.cnblogs.com/liu-Gray/p/5034794.html
Copyright © 2020-2023  润新知