• HashSet源码分析2


    package com.test1;
    
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Set;
    
    public class SetTest {
        public static void main(String[] args) {
            /*
             * Set<String> set = new HashSet<>();
             * System.out.println(set.add("abc"));
             * System.out.println(set.add("xyz"));
             * System.out.println(set.add("abc"));
             * 
             * for (Iterator<String> it = set.iterator(); it.hasNext();) {
             * System.out.println(it.next()); }
             */
            /*
             * String a = "abc"; String b = "abc"; System.out.println(a.hashCode());
             * System.out.println(b.hashCode());
             */
            Set<People> set2 = new HashSet<>();
            set2.add(new People("zhangsan"));
            set2.add(new People("lisi"));
            set2.add(new People("zhangsan"));
            for (Iterator<People> it = set2.iterator(); it.hasNext();) {
                System.out.println(it.next().getName());
            }
        }
    }
    
    class People {
        String name;
    
        public People(String name) {
            this.name = name;
        }
    
        public String getName() {
            return this.name;
        }
    
        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj instanceof People) {
                People people = (People) obj;
                if(this.name.equals(people.getName()));
                    return true;
            }
            return false;
        }
        @Override
        public int hashCode() {
            return this.name.hashCode();
        }
    }

    我们来看HashSet的构造方法:

      /**
         * 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<>();
        }

    竟然是new HashMap<>();

    关于HashSet与HashMap之间的关系:

    HashSet是由HashMap来实现的。HashSet里面的几乎所有的方法都是由HashMap实现的

    这个HashMap的key就是放进HashSet中的对象,value就是一个Object类型的对象,当调用HashSet的add方法时,实际上是向HashMap中增加了一行(key-value对),该key就是向HashSet中增加的那个对象,该行的value就是一个Object类型的对象。HashMap底层采用数组维护(数组中每个元素都是一个Map.Entry对象),调用增加的那个对象的hashCode方法,得到一个hashCode值,然后根据该值计算出一个数组的下标索引(计算出数组中的一个位置),将准备添加到Map中的对象与该位置处的对象进行比较(equals方法),如果相同,那么就向该位置处的那个对象(Map.Entry类型)的value值替换掉,否则沿着该Entry链继续重复上述过程,如果链的最后依然没有找到相同的对象,那么这个时候就将该对象添加到数组中,将数组中该位置处的Entry对象链接到这个对象后面:对于HashSet与HashMap来说,这样做是为了提高查找的效率,使得查找时间不随着Set或Map的大小而改变。

    查看add方法

        /**
         * Adds the specified element to this set if it is not already present.
         * More formally, adds the specified element <tt>e</tt> to this set if
         * this set contains no element <tt>e2</tt> such that
         * <tt>(e==null&nbsp;?&nbsp;e2==null&nbsp;:&nbsp;e.equals(e2))</tt>.
         * If this set already contains the element, the call leaves the set
         * unchanged and returns <tt>false</tt>.
         *
         * @param e element to be added to this set
         * @return <tt>true</tt> if this set did not already contain the specified
         * element
         */
        public boolean add(E e) {
            return map.put(e, PRESENT)==null;
        }
  • 相关阅读:
    听说高手都用记事本写C语言代码?真的假的!
    面向监狱编程,就靠它了!日子是越来越有判头了!
    如何把安静的程序员逼成话唠!
    想要自学编程?一个B站远远不够!
    2021年,学习C++还香吗?(文末赠书)!
    JVM--分代收集理论和垃圾收集算法
    Redis面试题
    基于RT1052 Aworks 使能GPIO输入功能(六)
    基于RT1052 Aworks 使能GPIO输出功能(五)
    基于RT1052 Aworks 使能ADC功能(四)
  • 原文地址:https://www.cnblogs.com/vincent4code/p/4798203.html
Copyright © 2020-2023  润新知