Hashset

作者: xiaoliman | 来源:发表于2017-08-12 11:44 被阅读0次

    1.先清除HashSet是怎么存储数据的.首先,往set里面添加数据的时候,会自动调用hashcode()方法,这个方法就是拿现在对象的hash码和set集合中其他数据的hash码比较(实际是跟哈希表中的记录的 hashcode比较 ) 如果都不相同,就直接添加数据.hash码是根据地址计算的,hash码不同,则地址肯定不同,则肯定不是一个对象.hashcode()就是用来筛选一些地址相同的数据.但是比较的hash码如果有相同的,则会去调用equals(),用来比较具体的属性值,看相同不相同.属性值相同,则不添加.不相同就会添加.
    2.如果set中存放的是int类型等一些基本类型 和 String类型的 是不允许内容重复的,即相同的内容如果存放在set里面是不允许的,这是因为这些类型的内容相同的话,他们的地址也相同.

    1. 如果想要实现 HashSet中 属性值相同就认为是同一个对象, 不添加到集合中,则需要重写hashcode和equals方法.因为原本hashcode()就是根据计算地址来进行比较的,所以重写的hashcode()不要计算地址,而是和属性值有关的来进行计算,如果属性值相同,则不会加入到集合中.

    4.下面5中hashcode()是自己写的,也可以快捷方式自动生成.如

    public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + age;
            result = prime * result + height;
            return result;
        }
    

    在这里有一个prime.这是为了把数的范围扩大,为了避免属性值不同,但是返回的result相同的情况,这种情况下就会调用equals方法.而实际上属性值不同时,如果把数的范围扩大,就不大有可能出现result相同的情况.(自行体会)

    3.person类

    package com.qf.demo3;
    
    public class Person {
    
        private int age;
        private  int height;
    
        public Person(int age, int height) {
            super();
            this.age = age;
            this.height = height;
        }
    
        public Person() {
            super();
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        
        @Override
        public String toString() {
            return "Person [age=" + age + ", height=" + height + "]";
        }
    
        // 是根据内存地址 经过一定的运算得到的
        //重写hashcode 也行者  得到属性值的hashcode 
        @Override
        public int hashCode() {
            //System.out.println("hashcode");
            int result = 0;
            result += age;// int  hashcode值就是自己本身
            result+= height;
            return result;
            // name sex  height 
            //  1   2     3        4 
            // 2    1     3       4 
            /**
             *  和 如果不一样      属性一定不一样
             *  
             *  和 一样    属性值   不一定一样
             *  只有  hashcode 值   相同的时候    才去调用equals方法 来确定 是否真的各个属性值都一样
             *  
             */ 
        }
        
        // 重写以后就是比较的属性值
        @Override
        public boolean equals(Object obj) {
            System.out.println("equals");
            if(obj == this){
                return true;
            }
            if(obj == null){
                return false;
            }
            
            if (obj instanceof Person) {
                Person person = (Person) obj;
                if(this.age == person.age  && this.height == person.height){
                    return true;
                }
            }
            return false;
        }
    }
    

    main:

    package com.qf.demo3;
    
    import java.util.HashSet;
    
    /**
     * Set  无序  不允许重复的
     * 
     * @author Administrator
     *HashSet   :   无序 是展示顺序与存入顺序不同\
     *哈希表: 存储很多的hashcode 
     *
     * 1  存储数据的时候  先  得到  这个数据的hashcode ,  拿这个hashcode  跟  哈希表中 的  记录的 hashcode比较   , 没有相同的 
     *          就认为 是不同的对象, 存入到集合
     * 
     *  如果相同    3+3 = 6
     *          2*3 = 6
     *  
     * 
     *  再去 调用 equals方法   比较每一个属性值 
     *
     *也没有从小到大排序
     */
    public class Test {
    
        public static void main(String[] args) {
            HashSet<String> set = new HashSet<>();
            set.add("d");
            set.add("a");
            set.add("w");
            set.add("w");// 不允许 重复
            System.out.println(set);
            
            HashSet<Integer> set2 = new HashSet<>();
            set2.add(8);
            set2.add(10);
            set2.add(1);
            set2.add(8);
            System.out.println(set2);
            
            // 每add一次 就会调用hashcode, 用 要添加的 数据的hash值 跟哈希表中 存储的多个哈希值对比
            // 如果不相同  则一定不是同一个对象  , 就添加到set集合中
            
            
            HashSet<Person> set3 = new HashSet<>();
            set3.add(new Person(7,1));
            set3.add(new Person(2,3));
            set3.add(new Person(2,3));
            set3.add(new Person(3,2));// 只要内容相同 就认为是同一个对象
            
            System.out.println(set3);
        }
    }
    
    

    总结:

    • 需求

    • HashSet中 属性值相同就认为是同一个对象, 不添加到集合中

    • 1 创建类, 重写 hashcode 和 equals
      hashcode 各个属性的hashcode值加和
      equals 每个属性值比较是否相同

    • 2 添加数据时 每添加一个数据就会 调用一次hashcode

    • 3 判断hashcode值 是否已经存在 ,如果不存在 直接将数据加到set集合中 ,不调用equals

    • 4 如果 hashcode值已经存在, 调用equals 方法

    • 如果eqeuals 返回 false 则认为是不同对象 添加到 set 中

    • 如果 equals 返回 true 真正的是 每个属性值 都相同 就认为是同一个对象 不添加到set 中

    相关文章

      网友评论

          本文标题:Hashset

          本文链接:https://www.haomeiwen.com/subject/hibdrxtx.html