Heim  >  Artikel  >  Java  >  Java-Verbesserungskapitel (24)-----HashSet

Java-Verbesserungskapitel (24)-----HashSet

黄舟
黄舟Original
2017-02-10 14:23:421154Durchsuche

Originaltext von: http://www.php.cn/

Im vorherigen Blogbeitrag ( Java-Verbesserung Kapitel (23) -----HashMap ) erklärt den Implementierungsprozess von HashMap im Detail. Für HashSet wird es basierend auf HashMap implementiert, und die unterste Ebene verwendet HashMap zum Speichern von Elementen . Wenn Sie also mit HashMap vertraut sind, ist HashSet so einfach!! HashSet erbt die AbstractSet-Klasse und implementiert die Schnittstellen Set, Cloneable und Serializable. Unter anderem stellt AbstractSet die Backbone-Implementierung der Set-Schnittstelle bereit und minimiert so den Arbeitsaufwand für die Implementierung dieser Schnittstelle. Die Set-Schnittstelle ist eine Sammlung, die keine doppelten Elemente enthält. Sie behält ihre eigene interne Reihenfolge bei, sodass ein wahlfreier Zugriff keinen Sinn ergibt.


Grundlegende Attribute
public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable



//基于HashMap实现,底层使用HashMap保存所有元素
private transient HashMap<E,Object> map;

 //定义一个Object对象作为HashMap的value
 private static final Object PRESENT = new Object();



HashSet kann vom Konstruktor aus gesehen werden. Alle Konstruktionen erstellen eine neue HashMap, und der letzte Konstruktor ist für den Paketzugriff und nicht öffentlich wird nur bei Verwendung von LinkedHashSet wirksam.

2. Methode

/**
         * 默认构造函数
         * 初始化一个空的HashMap,并使用默认初始容量为16和加载因子0.75。
         */
        public HashSet() {
            map = new HashMap<>();
        }
        
        /**
         * 构造一个包含指定 collection 中的元素的新 set。
         */
        public HashSet(Collection<? extends E> c) {
            map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
            addAll(c);
        }
        
        /**
         * 构造一个新的空 set,其底层 HashMap 实例具有指定的初始容量和指定的加载因子
         */
        public HashSet(int initialCapacity, float loadFactor) {
            map = new HashMap<>(initialCapacity, loadFactor);
        }
           
        /**
         * 构造一个新的空 set,其底层 HashMap 实例具有指定的初始容量和默认的加载因子(0.75)。
         */
        public HashSet(int initialCapacity) {
           map = new HashMap<>(initialCapacity);
        }
           
        /**
         * 在API中我没有看到这个构造函数,今天看源码才发现(原来访问权限为包权限,不对外公开的)
         * 以指定的initialCapacity和loadFactor构造一个新的空链接哈希集合。
         * dummy 为标识 该构造函数主要作用是对LinkedHashSet起到一个支持作用
         */
        HashSet(int initialCapacity, float loadFactor, boolean dummy) {
           map = new LinkedHashMap<>(initialCapacity, loadFactor);
        }


Da HashSet auf HashMap basiert, gilt für HashSet der Implementierungsprozess seiner Methode ist ganz einfach. Die Methode iterator() gibt einen Iterator zurück, der die Elemente in dieser Menge durchläuft. Die Reihenfolge, in der die Elemente zurückgegeben werden, ist nicht spezifisch. Der zugrunde liegende Aufruf des HashMap-Schlüsselsatzes gibt alle Schlüssel zurück. Dies spiegelt wider, dass alle Elemente im HashMap-Schlüssel gespeichert sind und der Wert das verwendete PRESENT-Objekt ist, das statisch endgültig ist.

size() gibt die Anzahl der Elemente in dieser Menge (die Kapazität der Menge) zurück ). Die unterste Ebene ruft die Größenmethode von HashMap auf und gibt die Größe des HashMap-Containers zurück.

isEmpty(), ermittelt, ob der HashSet()-Satz leer ist, gibt zurück, wenn dies der Fall ist ist leer
public Iterator<E> iterator() {
        return map.keySet().iterator();
    }
true, andernfalls wird false

zurückgegeben.

public int size() {
        return map.size();
    }

contains(), bestimmt, ob ein Element in HashSet() existiert, existiert. Gibt true zurück , andernfalls wird false zurückgegeben. Genauer gesagt sollte diese Beziehung erfüllt sein, um „true“ zurückzugeben: (o==null ? e==null : o.equals(e)). Die unterste Ebene ruft „containsKey“ auf, um zu bestimmen, ob der Schlüsselwert von HashMap leer ist.

public boolean isEmpty() {
        return map.isEmpty();
    }

add() Wenn dieser Satz das angegebene Element noch nicht enthält, fügen Sie das angegebene hinzu Element. Wenn dieser Satz kein e2 enthält, das (e==null ? e2==null : e.equals(e2)) erfüllt, wird e2 zum Satz hinzugefügt, andernfalls wird es nicht hinzugefügt und false zurückgegeben. Da die unterste Ebene die Put-Methode von HashMap verwendet, um key = e, value = PRESENT in ein Schlüssel-Wert-Paar zu konstruieren, überschreibt der Wert den ursprünglichen Wert, wenn e im Schlüssel von HashMap vorhanden ist, der Schlüssel bleibt jedoch unverändert Wenn dem HashSet ein vorhandenes e-Element hinzugefügt wird, wird das neu hinzugefügte Element nicht in der HashMap gespeichert, sodass die Funktion erfüllt ist, dass die Elemente im HashSet nicht wiederholt werden.

                                                                          

public boolean contains(Object o) {
        return map.containsKey(o);
    }

Die unterste Ebene verwendet die Remove-Methode von HashMap, um den angegebenen Eintrag zu löschen.

public void clear() {
        map.clear();
    }

          clear从此 set 中移除所有元素。底层调用HashMap的clear方法清除所有的Entry。

public Object clone() {
        try {
            HashSet<E> newSet = (HashSet<E>) super.clone();
            newSet.map = (HashMap<E, Object>) map.clone();
            return newSet;
        } catch (CloneNotSupportedException e) {
            throw new InternalError();
        }
    }

          clone返回此 HashSet 实例的浅表副本:并没有复制这些元素本身。

          后记:

          由于HashSet底层使用了HashMap实现,使其的实现过程变得非常简单,如果你对HashMap比较了解,那么HashSet简直是小菜一碟。有两个方法对HashMap和HashSet而言是非常重要的,下篇将详细讲解hashcode和equals。

---------------------------------------------------------------------------------------------------------

以上就是java提高篇(二四)-----HashSet的内容,更多相关内容请关注PHP中文网(www.php.cn)!



Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn