zoukankan      html  css  js  c++  java
  • java容器类:HashSet

    HashSet是基于HashMap实现的,之前有被问到HashSet和HashMap的区别,我只死记了一条:HashSet的存储的内容不可重复,HashMap可以重复.那么HashSet基于HashMap实现,怎么做可以让HashSet中的对象不重复呢?

    HashSet源码##

    //Hashset类内部维护了一个HashMap类,提供5种构造方法用于实例化map类.
    private transient HashMap<E,Object> map;
    public HashSet() {
        map = new HashMap<>();
    }
    public HashSet(Collection<? extends E> c) {
        map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
        addAll(c);
    }
    public HashSet(int initialCapacity, float loadFactor) {
        map = new HashMap<>(initialCapacity, loadFactor);
    }
    public HashSet(int initialCapacity) {
        map = new HashMap<>(initialCapacity);
    }
    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
    }
    

    HashSet的size,isEmpty,contains,clear,add,remove等方法都是基于HashMap的对应方法实现的,而HashSet的不重复特性依靠add方法

    //HashSet被调用的时候生成的一个简单对象    
    private static final Object PRESENT = new Object();
    
    //调用HashMap的put方法,将要插入的对象作为key,PRESENT作为值,两者联合为键值对存入map中
    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }
    
    public V put(K key, V value) {
        if (table == EMPTY_TABLE) {
            inflateTable(threshold);
        }
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key);
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
             //第一步首先判断key的哈希码是否一致,第二步判断代表key的对象是否一致,如果判断都通过的话新的值替换旧的值.
             //因此反复地传入相同对象,只会在一个位置重复替换没有实际意义的PRESENT对象(或者说根本没换过),达到了防重复的目的.
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {   
                V oldValue = e.value;
                e.value = value;
            //该方法在LinkedList有实现.
                e.recordAccess(this);
                return oldValue;
            }
        }
    
        modCount++;
            //如果无法匹配已经存在的键,则插入一个新的键值对.
        addEntry(hash, key, value, i);
        return null;
    }
    
    • 判断是否重复的一个重要依据是对象的hashCode方法和euqal方法,我们可以通过重写这两个方法来自由制定我们的防重复的规则.
    • 例如我们判断对象是否重复基于其中的一个属性
    public class Person {
    
    public Integer age = 14;
    
    @Override
    public int hashCode() {
    	return age.hashCode();
    }
    
    @Override
    public boolean equals(Object obj) {
    	Person person = (Person) obj;
    	if(person.age == this.age) {
    		return true;
    	}
    	return false;
    }
    }
    

    这样两个age相同的Person类就只能有一个被纳入HashSet中

  • 相关阅读:
    学习笔记15—Python 存储集
    学习笔记14—Python error集
    学习笔记13—python DataFrame获取行数、列数、索引及第几行第几列的值
    学习笔记12—linux下文件的复制、移动与删除
    学习笔记11—MATLAB 界面设计
    学习笔记10—Python 绘图集
    学习笔记9—python数据表的合并(join(), merge()和concat())
    学习笔记8—MATLAB中奇异值处理办法
    make ffmpeg makefile
    Linux Socket
  • 原文地址:https://www.cnblogs.com/itsrobin/p/5134560.html
Copyright © 2011-2022 走看看