2016-05-01 1 views
0

Hier ist ein Code des Treesets des benutzerdefinierten Objekts.Wie der Wert in die benutzerdefinierte Vergleichsfunktion im Treeset übernommen wird

package com.java2novice.treeset; 

import java.util.Comparator; 
import java.util.TreeSet; 

public class MyCompUserDefine { 

    public static void main(String a[]){ 
     //By using name comparator (String comparison) 
     TreeSet<Empl> nameComp = new TreeSet<Empl>(new MyNameComp()); 
     nameComp.add(new Empl("Ram",3000)); 
     nameComp.add(new Empl("John",6000)); 
     nameComp.add(new Empl("Crish",2000)); 
     nameComp.add(new Empl("Tom",2400)); 
     for(Empl e:nameComp){ 
      System.out.println(e); 
     } 
     System.out.println("==========================="); 
     //By using salary comparator (int comparison) 
     TreeSet<Empl> salComp = new TreeSet<Empl>(new MySalaryComp()); 
     salComp.add(new Empl("Ram",3000)); 
     salComp.add(new Empl("John",6000)); 
     salComp.add(new Empl("Crish",2000)); 
     salComp.add(new Empl("Tom",2400)); 
     for(Empl e:salComp){ 
      System.out.println(e); 
     } 
    } 
} 

class MyNameComp implements Comparator<Empl>{ 

    @Override 
    public int compare(Empl e1, Empl e2) { 
     return e1.getName().compareTo(e2.getName()); 
    } 
} 

class MySalaryComp implements Comparator<Empl>{ 

    @Override 
    public int compare(Empl e1, Empl e2) { 
     if(e1.getSalary() > e2.getSalary()){ 
      return 1; 
     } else { 
      return -1; 
     } 
    } 
} 

class Empl{ 

    private String name; 
    private int salary; 

    public Empl(String n, int s){ 
     this.name = n; 
     this.salary = s; 
    } 

    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 
    public int getSalary() { 
     return salary; 
    } 
    public void setSalary(int salary) { 
     this.salary = salary; 
    } 
    public String toString(){ 
     return "Name: "+this.name+"-- Salary: "+this.salary; 
    } 
} 

Meine Frage ist, wenn ich MyNameComp nenne() oder MySalaryComp(), dann nenne ich den Konstruktor nur ohne jeden Wert übergeben. Aber wie wird Wert oder Objekt der Klasse EMP1 weitergegeben?

Antwort

0

TreeSet behält seine Elemente sortiert. Wenn Sie einen Vergleicher angeben, verwendet er diesen benutzerdefinierten Vergleicher (in Ihrem Fall MyNameComp() oder MySalaryComp()), um sie zu vergleichen und zu sortieren. Sie müssen nichts aufrufen, TreeSet wird intern damit umgehen.

0

Die von Ihnen erstellten Objekte TreeSet sind für die Verwendung des Komparators verantwortlich, den Sie bei der Instanziierung übergeben haben.

Wie die TreeSet sollte es dich nicht kümmern, weil es ein Implementierungsdetail ist. Die TreeSet garantiert nur, dass der von Ihnen bereitgestellte Komparator bei Bedarf verwendet wird. Sie müssen nicht darüber nachdenken ... aber nur zum Glück, schauen wir uns die Quelle an (bitte beachten Sie, dass Sie sich nicht auf Implementierungsdetails von Klassen verlassen sollten, da diese frei sind, wenn Sie eine API konsumieren Sie nur sicher sein kann, was ein expliziter Teil der Schnittstelle!)

beginnen wir mit dem TreeSet constructor that takes a Comparator as an argument beginnen, ist es das, was Sie anrufen, wenn Sie Ihre TreeSet Instanzen in den

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

bereitgestellten Beispiele erstellen Wir können sehen, dass the constructor den Komparator verwendet, um einen Aufruf einen anderen TreeSet Konstruktor zu instanziieren. Die hier erstellte TreeMap wird verwendet, um die Artikel in der TreeSet zu speichern.

Lassen wir es dabei, ohne zu überprüfen, was innerhalb der TreeMap passiert. Wir müssen nur wissen, dass die TreeMap ist, was die Artikel tatsächlich speichert. Dieses Wissen wird sich als nützlich erweisen, wenn wir uns ansehen, was passiert, wenn Sie Elemente hinzufügen.

Sie fügen alle Elemente mit der TreeSet#add method ein, die dieselbe Map verwendet, die beim Aufruf des Konstruktors erstellt wurde.

public boolean More ...add(E e) { 
    return m.put(e, PRESENT)==null; 
} 

Die m Objekt ist die TreeMap innerhalb des Konstruktors instantiiert. Da wir wissen, dass es ein ist und dass die put Methode verwendet wird, können wir uns ansehen, was es macht.

Hier ist die Implementierung von TreeMap#put

Dieses Verfahren einen Komparator verwendet, die bei näherer Betrachtung, die gleiche sein, stellt sich heraus, die verwendet wurde, wenn das in dem TreeMapTreeSet Konstruktor zu erstellen.

public V More ...put(K key, V value) { 
    Entry<K,V> t = root; 
    if (t == null) { 
     // TBD: 
     // 7: (coll) Adding null to an empty TreeSet should 
     // throw NullPointerException 
     // 
     // compare(key, key); // type check 
     root = new Entry<K,V>(key, value, null); 
     size = 1; 
     modCount++; 
     return null; 
    } 
    int cmp; 
    Entry<K,V> parent; 
    // split comparator and comparable paths 
    Comparator<? super K> cpr = comparator; 
    if (cpr != null) { 
     do { 
      parent = t; 
      cmp = cpr.compare(key, t.key); 
      if (cmp < 0) 
       t = t.left; 
      else if (cmp > 0) 
       t = t.right; 
      else 
       return t.setValue(value); 
     } while (t != null); 
    } 
    else { 
     if (key == null) 
      throw new NullPointerException(); 
     Comparable<? super K> k = (Comparable<? super K>) key; 
     do { 
      parent = t; 
      cmp = k.compareTo(t.key); 
      if (cmp < 0) 
       t = t.left; 
      else if (cmp > 0) 
       t = t.right; 
      else 
       return t.setValue(value); 
     } while (t != null); 
    } 
    Entry<K,V> e = new Entry<K,V>(key, value, parent); 
    if (cmp < 0) 
     parent.left = e; 
    else 
     parent.right = e; 
    fixAfterInsertion(e); 
    size++; 
    modCount++; 
    return null; 
} 

Dies ist ein wenig kompliziert, und man müßte durch den Rest der Umsetzung lesen ein umfassendes Verständnis davon, was hier passiert, aber es ist deutlich zu erkennen, dass der bereitgestellten Komparator verwendet wird.

Die Quintessenz hier ist jedoch, dass diese für Sie oder Ihren Code als Client der Sammlungen API keine Rolle spielen sollte. Sie sollten sich nur darauf verlassen, was im Javadoc der Methoden public oder protected explizit angegeben ist.

Sie einen Blick auf the JDK 8 version nehmen können, um zu sehen, dass die Einbauten (wenn auch sehr leicht)

Der Grund können Sie sicher sein, sich geändert haben, dass ein TreeMap und die bereitgestellte Comparator verwendet werden, weil es Teil der TreeSet ist ' s API. Um es mit dem TreeSet Javadoc:

(a TreeSet ist) Eine NavigableSet Implementierung basiert auf einer TreeMap. Die Elemente werden in ihrer natürlichen Reihenfolge geordnet oder durch eine Comparator, die zur festgelegten Erstellungszeit bereitgestellt wird, abhängig davon, welcher Konstruktor verwendet wird.

Die Änderung eines dieser Dinge würde den Vertrag brechen.

Verwandte Themen