2017-09-23 2 views
0

Ich habe eine Klasse mit dem Namen Empl und zwei Komparatoren mit den Namen MySalaryComp und MyNameComp.Nullen in TreeMap mit Comparator

Wenn ich diesen Code ausführen bekomme ich null als Wert in MySalaryComp wie in der Ausgabe unten gezeigt.

public class Test{ 

    public static void main(String a[]) { 
     TreeMap<Empl, String> tm = new TreeMap<Empl, String>(new MyNameComp()); 
     tm.put(new Empl("zzz", 3000), "RAM"); 
     tm.put(new Empl("aaa", 6000), "JOHN"); 
     Set<Empl> keys = tm.keySet(); 
     for (Empl key : keys) { 
      System.out.println(key + " ==> " + tm.get(key)); 
     } 

     TreeMap<Empl, String> trmap = new TreeMap<Empl, String>(new MySalaryComp()); 
     trmap.put(new Empl("zzz", 3000), "RAM"); 
     trmap.put(new Empl("aaa", 6000), "JOHN"); 
     Set<Empl> ks = trmap.keySet(); 
     for (Empl key : ks) { 
      System.out.println(key + " ==> " + trmap.get(key)); 
     } 
    } 
} 

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; 
    } 


} 

Der Ausgang des obigen Code ist:

Name: aaa-- Salary: 6000 ==> JOHN 
Name: zzz-- Salary: 3000 ==> RAM 
Name: zzz-- Salary: 3000 ==> null 
Name: aaa-- Salary: 6000 ==> null 

Kann mir jemand helfen, warum Nullwerte verstehen zeigen? Und wie man es repariert.

Antwort

2

Ihr Vergleicher ist nicht korrekt implementiert. Lesen Sie auf den JavaDocs up:

https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html

Vergleicht seine beiden Argumente für Ordnung. Gibt eine negative Ganzzahl, Null oder eine positive ganze Zahl zurück, wenn das erste Argument kleiner als, gleich oder größer als die zweite Zahl ist.

Versuchen Sie folgendes:

@Override 
public int compare(Employee e1, Employee e2) { 
    return e1.getSalary() - e2.getSalary(); 
} 

Warum brauchen Sie 0 zurück?
Wenn Sie sich den Quellcode von TreeMap schauen, werden Sie sehen:

final Entry<K,V> getEntry(Object key) { 
    // Offload comparator-based version for sake of performance 
    if (comparator != null) 
    return getEntryUsingComparator(key); 
    if (key == null) 
    throw new NullPointerException(); 
    @SuppressWarnings("unchecked") 
    Comparable<? super K> k = (Comparable<? super K>) key; 
    Entry<K,V> p = root; 
    while (p != null) { 
    int cmp = k.compareTo(p.key); 
    if (cmp < 0) 
     p = p.left; 
    else if (cmp > 0) 
     p = p.right; 
    else 
     return p; // <--Here 
    } 
    return null; 
} 

Wenn der Komparator nie 0 ist, er wird dereferenzieren das Kind Zweig, der null sein wird.

Nebenbei bemerkt: Sie können auch Ihren Komparator funktional, wie so machen:

Comparator<Employee> salaryComparator = (e1, e2) -> (e1.getSalary() - e2.getSalary()); 
TreeMap<Employee, String> trmap = new TreeMap<>(salaryComparator); 
+0

Warum Rückkehr 0 in get() -Methode von treemap reflektieren, bitte erklären –

+0

lol, weil es 0 zurückgeben muss auf die erste setzen –

+0

Aber ich bin in der Lage, die Elemente in KT richtig? Problem ist, wenn ich die Elemente von KT abhole. Bitte gehen Sie durch die obige Antwort –

1

Weil mein Gehalt Komparator 0 nie zurück, wenn zwei Objekte gleiches Gehalt haben.

Sie müssen MySalaryComp beheben, um Null zurückzugeben, wenn die Gehälter beider Objekte gleich sind.

+0

Ja funktioniert gut, Könnten Sie bitte erklären, warum die Rückgabe von 0 die Kartenausgabe ändert –

+0

Einfach, weil treemap auf angegebenen Komparator bei der Suche der angegebenen Schlüssel beruht. Wenn der Vergleicher nicht in der Lage ist zu bestimmen, ob zwei Objekte gleich sind, so wird die Karte den gegebenen Schlüssel nie berücksichtigen. – skadya

+0

danke für deine Antwort –

0

den Komparator richtig außer Kraft setzen: Sie können die eingebauten Komparator integer verwenden

return Integer.valueOf(e1.getSalary()).compareTo(e2.getSalary());