2017-09-23 67 views
0

我有一個名爲Empl的類和兩個名爲MySalaryCompMyNameComp的比較器。使用比較器在TreeMap中獲取空值

當我運行此代碼時,我得到null作爲MySalaryComp中的值,如下面的輸出所示。

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


} 

以上代碼的輸出是:

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

有人能幫助我理解爲什麼空值顯示?以及如何解決它。

回答

2

您的比較器沒有正確實現。 閱讀上JavaDoc中:

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

比較它的兩個參數的順序。返回一個負整數 零,或者一個正整數,因爲第一個參數小於,等於 到或大於秒。

試試這個:

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

爲什麼你需要返回0?
如果你看樹形圖的源代碼,你會看到:

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

如果比較是永遠不爲0,他將間接引用的子分支,這將是空的。

旁註: 您也可以讓你的比較功能,像這樣:

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

爲什麼返回0,在GET()的映像樹的方法反映,請解釋 –

+0

笑,因爲它需要在返回0第一次投入 –

+0

但是我能夠把這些元素放在KT中嗎?問題是當我從KT獲取元素時。請通過以上的答案 –

1

因爲我的工資比較不會返回0,當兩個對象具有相同的薪水。

當兩個對象的薪水相同時,您需要修復MySalaryComp以返回零。

+0

是的工作很好,你能解釋爲什麼返回0會改變地圖輸出 –

+0

只是因爲treemap在搜索給定的鍵時依賴給定的比較器。如果比較器不能確定兩個對象是相同的,那麼地圖會考慮給定的鍵從不存儲 – skadya

+0

感謝您的回答 –

0

正確地重寫比較:您可以使用內置整數比較

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