Heim > Java > javaLernprogramm > Detaillierte Analyse des Quellcodes der Set in Java-Sammlungsklasse

Detaillierte Analyse des Quellcodes der Set in Java-Sammlungsklasse

黄舟
Freigeben: 2017-10-10 10:16:51
Original
1641 Leute haben es durchsucht

Der folgende Editor bietet Ihnen eine detaillierte Erklärung der Quellcodeanalyse der Set-in-Java-Collection-Klasse. Der Herausgeber findet es ziemlich gut, deshalb werde ich es jetzt mit Ihnen teilen und es allen als Referenz geben. Folgen wir dem Editor, um einen Blick darauf zu werfen

Set-Sammlung erbt wie List von der Collection-Schnittstelle. Zu den häufig verwendeten Implementierungsklassen gehören HashSet und TreeSet. Es ist erwähnenswert, dass HashSet über HashMap und TreeSet über TreeMap implementiert wird, sodass weder HashSet noch TreeSet über eine eigene Datenstruktur verfügen. Die Details können wie folgt zusammengefasst werden:

• Die Elemente in der Set-Sammlung können nicht Wiederholen, das heißt, die Elemente sind eindeutig

•HashSet wird durch den Hashwert des Elements gespeichert, ist also ungeordnet und lässt höchstens ein Nullobjekt zu

•TreeSet wird durch gespeichert die Größe des Elements, also ist es geordnet, und Nullobjekte sind nicht erlaubt

• Die Set-Sammlung verfügt über keine Get-Methode, daher können die Elemente nur über Iteratoren (Iterator) und Direktzugriff durchlaufen werden ist nicht möglich

1 .HashSet

Ein Teil des Quellcodes von HashSet wird unten angegeben, um seine Implementierung zu verstehen.


static final long serialVersionUID = -5024744406713321676L;

 private transient HashMap<E,Object> map;

 // Dummy value to associate with an Object in the backing Map
 private static final Object PRESENT = new Object();
Nach dem Login kopieren

Wenn wir den Quellcode betrachten, wissen wir, dass die Daten von HashSet in der Instanzobjektkarte von HashMap gespeichert sind und dem Schlüssel in entsprechen Karte und Objekt Die Typreferenz PRESENT ist ein virtueller Wert, der dem Wert in der Karte entspricht und keine praktische Bedeutung hat. Wenn wir an einige Merkmale von HashMap denken: ungeordneter Speicher, eindeutiger Schlüsselwert usw., können wir natürlich die Merkmale nicht wiederholbarer Set-Sammlungselemente und die ungeordneten Speichermerkmale von HashSet verstehen.

Das Folgende ist ein Verständnis der grundlegenden Verwendung von HashSet aus der Perspektive des Quellcodes:

•Konstruktor (vier Typen)

1.HashSet() Leerer Konstruktor, initialisiert eine leere HashMap

2.HashSet(Collection c) Übergeben Sie eine Teilmenge c, wird zum Initialisieren von HashMap verwendet

3.HashSet(int initialCapacity, float loadFactor) Initialisiert eine leere HashMap und gibt die anfängliche Kapazität und den Ladefaktor an

4.HashSet(int initialCapacity) Initialisiert eine leere HashMap und geben Sie die Anfangskapazität an


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);
 }
Nach dem Login kopieren

• Element einfügen

1.add(E e ) Fügen Sie das angegebene Element ein (implementiert durch Aufrufen der Put-Methode von HashMap)


   Set<String> hashSet = new HashSet<String>();
   hashSet.add("D");
   hashSet.add("B");
   hashSet.add("C");
   hashSet.add("A");
Nach dem Login kopieren

•Finden Sie das Element

1. enthält(Objekt o) Bestimmen Sie, ob die Menge das angegebene Element enthält (implementiert durch Aufrufen der Methode „containsKey“ von HashMap)


  public boolean contains(Object o) {
   return map.containsKey(o);
  }
Nach dem Login kopieren

2 Da es keine Get-Methode gibt die Implementierungsklasse von HashSet, also nur Kann sequentiell durch Iteratoren durchlaufen werden, aber nicht zufällig darauf zugegriffen werden (Aufruf der Iterator-Implementierung von keySet in HashMap)


  public Iterator<E> iterator() {
   return map.keySet().iterator();
  }
Nach dem Login kopieren

Anwendungsbeispiel :


Set<String> hashSet = new HashSet<String>();
  hashSet.add("D");
  hashSet.add("B");
  hashSet.add("C");
  hashSet.add("A");
  for (Iterator iterator = hashSet.iterator(); iterator.hasNext();) {
   String string = (String) iterator.next();
   System.out.print(string+" ");
  }//D A B C
Nach dem Login kopieren

•Elemente ändern

Da der Schlüsselwert in HashMap nicht geändert werden kann, kann HashSet nicht geändert werden elements

•Element löschen

1.remove(Object o) Löscht das angegebene Element (implementiert durch Aufrufen der Remove-Methode in HashMap, der Rückgabewert ist true oder false )


  public boolean remove(Object o) {
   return map.remove(o)==PRESENT;
  }
Nach dem Login kopieren

2.clear() Löscht das Element (implementiert durch Aufruf der Clear-Methode in HashMap, kein Rückgabewert)


public void clear() {
   map.clear();
  }
Nach dem Login kopieren

2.TreeSet

TreeSet ist die einzige Implementierungsklasse der SortedSet-Schnittstelle. Wie bereits erwähnt, verfügt TreeSet nicht über eine eigene Datenstruktur, sondern wird über TreeMap implementiert. Daher ist TreeSet auch eine Speicherstruktur, die auf roten und schwarzen Binärbäumen basiert. Daher lässt TreeSet keine Nullobjekte zu und wird in der richtigen Reihenfolge gespeichert (standardmäßig aufsteigende Reihenfolge). .


private transient NavigableMap<E,Object> m;
 
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
Nach dem Login kopieren

Die NavigableMap im obigen Quellcode ist eine von SrotedMap geerbte Schnittstelle, und ihre Implementierungsklasse ist TreeMap, sodass die Daten im TreeSet über die TreeMap gespeichert werden Auch hier ist PRESENT ein virtueller Wert ohne praktische Bedeutung.

Das Folgende ist ein Verständnis der grundlegenden Verwendung von HashSet aus der Perspektive des Quellcodes:

•Konstruktor (vier Typen)

1.TreeSet() Leerer Konstruktor, initialisiert eine leere TreeMap, standardmäßig in aufsteigender Reihenfolge angeordnet

2.TreeSet(Comparator

3.TreeSet(Collection c) Übergeben Sie eine Teilmenge c, die zum Initialisieren des TreeMap-Objekts verwendet wird. Die Standardeinstellung ist aufsteigend order

4.TreeSet(SortedSet s) übergibt eine geordnete Teilmenge s, um das TreeMap-Objekt mithilfe des Teilmengenkomparators zu initialisieren


public TreeSet() {
  this(new TreeMap<E,Object>());
 }

 public TreeSet(Comparator<? super E> comparator) {
  this(new TreeMap<>(comparator));
 }

 public TreeSet(Collection<? extends E> c) {
  this();
  addAll(c);
 }

 public TreeSet(SortedSet<E> s) {
  this(s.comparator());
  addAll(s);
 }
Nach dem Login kopieren

Anwendungsbeispiel


//自定义一个比较器,实现降序排列
  Set<Integer> treeSet = new TreeSet<Integer>(new Comparator<Integer>() {

   @Override
   public int compare(Integer o1, Integer o2) {
//    return 0;  //默认升序
    return o2.compareTo(o1);//降序
   }
  });
  treeSet.add(200);
  treeSet.add(120);
  treeSet.add(150);
  treeSet.add(110);
  for (Iterator iterator = treeSet.iterator(); iterator.hasNext();) {
   Integer integer = (Integer) iterator.next();
   System.out.print(integer+" ");
  } //200 150 120 110
Nach dem Login kopieren


ArrayList<Integer> list = new ArrayList<Integer>();
  list.add(300);
  list.add(120);
  list.add(100);
  list.add(150);
  System.out.println(list); //[300, 120, 100, 150]
  
  //传入一个子集,默认升序排列
  TreeSet<Integer> treeSet = new TreeSet<Integer>(list);
  for (Iterator iterator = treeSet.iterator(); iterator.hasNext();) {
   Integer integer = (Integer) iterator.next();
   System.out.print(integer+" ");
  }//100 120 150 300
Nach dem Login kopieren


/*
   * 传入一个有序的子集,采用子集的比较器
   *  注意子集的类型必须是SortedSet及其子类或者实现类,否则将采用默认的比较器
   *  所以此处subSet的类型也可以是TreeSet。
   */
  
  SortedSet<Integer> subSet = new TreeSet<Integer>(new Comparator<Integer>() {

   @Override
   public int compare(Integer o1, Integer o2) {
//    return 0;  //默认升序
    return o2.compareTo(o1);//降序
   }
  });
  subSet.add(200);
  subSet.add(120);
  subSet.add(150);
  subSet.add(110);
  for (Iterator iterator = subSet.iterator(); iterator.hasNext();) {
   Integer integer = (Integer) iterator.next();
   System.out.print(integer+" ");
  } //200 150 120 110 
  
  System.out.println();
  Set<Integer> treeSet = new TreeSet<Integer>(subSet);
  for (Iterator iterator = treeSet.iterator(); iterator.hasNext();) {
   Integer integer = (Integer) iterator.next();
   System.out.print(integer+" ");
  }//200 150 120 110 
  
  System.out.println();
  treeSet.add(500);
  treeSet.add(100);
  treeSet.add(105);
  for (Iterator iterator = treeSet.iterator(); iterator.hasNext();) {
   Integer integer = (Integer) iterator.next();
   System.out.print(integer+" ");
  }//500 200 150 120 110 105 100
Nach dem Login kopieren

• Elemente einfügen

1.add(E e) Fügt das angegebene Element ein (implementiert durch Aufruf der put-Methode von TreeMap)

2.addAll(Collection c) Einfügen einer Teilmenge c


ArrayList<Integer> list = new ArrayList<Integer>();
  list.add(300);
  list.add(120);
  list.add(100);
  list.add(150);
  System.out.println(list); //[300, 120, 100, 150]
  
  Set<Integer> treeSet = new TreeSet<Integer>();
  
  //插入一个子集,默认升序
  treeSet.addAll(list);
  for (Iterator iterator = treeSet.iterator(); iterator.hasNext();) {
   Integer integer = (Integer) iterator.next();
   System.out.print(integer+" ");
  }//100 120 150 300
Nach dem Login kopieren

• Element finden

1.contains(Object o) Bestimmen ob das angegebene Objekt in der Sammlung enthalten ist (implementiert durch Aufruf der Methode „containsKey“ von TreeMap)

2.与HashSet一样,TreeSet的实现类中没有get方法,所以只能通过迭代器依次遍历,而不能随机访问(调用TreeMap中keySet的迭代器实现)。

•修改元素

TreeSet不能进行修改元素的操作,原因与HashSet一样。

•删除元素

1.remove(Object o) 删除指定元素(调用TreeMap中的remove方法实现,返回true或者false)


  public boolean remove(Object o) {
   return m.remove(o)==PRESENT;
  }
Nach dem Login kopieren

2.clear() 清空元素(调用TreeMap中的clear方法实现,无返回值)


  public void clear() {
   m.clear();
  }
Nach dem Login kopieren

应用示例:


ArrayList<Integer> list = new ArrayList<Integer>();
  list.add(300);
  list.add(120);
  list.add(100);
  list.add(150);
  System.out.println(list); //[300, 120, 100, 150]
  
  Set<Integer> treeSet = new TreeSet<Integer>();
  
  //插入一个子集,默认升序
  treeSet.addAll(list);
  for (Iterator iterator = treeSet.iterator(); iterator.hasNext();) {
   Integer integer = (Integer) iterator.next();
   System.out.print(integer+" ");
  }//100 120 150 300 
  
  System.out.println(treeSet.remove(100));//true
  for (Iterator iterator = treeSet.iterator(); iterator.hasNext();) {
   Integer integer = (Integer) iterator.next();
   System.out.print(integer+" ");
  }//120 150 300 
  
  treeSet.clear();
  System.out.println(treeSet.size());//0
Nach dem Login kopieren

至此,HashSet和TreeSet的存储结构及基本用法介绍完毕。

Das obige ist der detaillierte Inhalt vonDetaillierte Analyse des Quellcodes der Set in Java-Sammlungsklasse. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage