2013-01-21 87 views
1

我是Java新手,正在使用本站上的TreeMap代码示例,但是当我尝试遍历TreeMap时,我得到一个空值列表,但是当我直接打印地图时,可以看到键/值对。我该如何纠正这一点?当我从TreeMap打印出值时,为什么会得到空值列表?

import java.util.*; 
public class Testing { 

    public static void main(String[] args) { 

     HashMap<String,Double> map = new HashMap<String,Double>(); 
     ValueComparator1 bvc = new ValueComparator1(map); 
     TreeMap<String,Double> sorted_map = new TreeMap<String,Double>(bvc); 

     map.put("A",99.5); 
     map.put("B",67.4); 
     map.put("C",67.4); 
     map.put("D",67.3); 

     System.out.println("unsorted map: "+map); 

     sorted_map.putAll(map); 


     System.out.println("results: "+sorted_map); 

     for(String key: sorted_map.keySet()) 
     { 
      System.out.println(sorted_map.get(key)); //null values-Why? 
     } 
    } 
} 

class ValueComparator1 implements Comparator<String> { 

    Map<String, Double> base; 
    public ValueComparator1(Map<String, Double> base) { 
     this.base = base; 
    } 

    // Note: this comparator imposes orderings that are inconsistent with equals.  
    public int compare(String a, String b) { 
     if (base.get(a) >= base.get(b)) { 
      return -1; 
     } else { 
      return 1; 
     } // returning 0 would merge keys 
    } 
} 

回答

6

它不起作用,因为当给定相同的键时,比较器不返回0,例如,比较(“A”,“A”)。更改为

public int compare(String a, String b) { 
     Double va = base.get(a); 
     Double vb = base.get(b); 
     if(va > vb) { 
      return -1; 
     } else if(va < vb) { 
      return 1; 
     } else { 
      return a.compareTo(b); 
     } 
    } 

它会工作。

+0

实现那只是需要的东西?因为在这个例子中我所有的键都不同。仍然不明白这个编辑背后的原因。它工作顺便。 – lord12

+0

这是必要的,因为当你调用get(“A”)时,并且地图查看“A”的条目时,原始比较器说明键不相等,所以它不会返回该条目。 –

3

对不起,但你的例子是有点颠倒。您将键放入有序映射(树形图)中,然后使用这些值作为键,这是您通过值进行比较的意义。看起来您正在寻找处理具有密钥和值的对象,因此您可能需要考虑以下内容。这肯定是OOP处理“复合”概念的方式,就像你用地图建模的那样。

class Pair implements Comparable<Pair> { 
    String value; 
    double key; 

    Pair(String value, double key) { 
     this.value = value; 
     this.key = key; 
    } 

    public int compareTo(Pair p) { 
     return Double.compare(key, p.key); 
    } 

    public String toString(Pair p) { 
     return value + "," + key; 
    } 
} 

static void main(String[] args) { 
    Set<Pair> unsortedSet = new HashSet<Pair>(); 
    unsortedSet.add(new Pair("A", 99.5)); 
    unsortedSet.add(new Pair("B", 67.4)); 
    unsortedSet.add(new Pair("C", 67.4)); 
    unsortedSet.add(new Pair("D", 67.3)); 

    Set<Pair> sortedSet = new TreeSet<Pair>(); 
    sortedSet.add(new Pair("A", 99.5)); 
    sortedSet.add(new Pair("B", 67.4)); 
    sortedSet.add(new Pair("C", 67.4)); 
    sortedSet.add(new Pair("D", 67.3)); 

    System.out.println("Unsorted set: " + unsortedSet); 
    System.out.println("Sorted set: " + sortedSet); 

    for (Pair pair : sortedSet) { 
     System.out.println(pair); 
    } 
} 
1

由于您的比较器永远不会返回0 TreeMap.get()不起作用。你仍然可以遍历TreeMap的条目是这样

for (Entry<String, Double> e : sorted_map.entrySet()) { 
     System.out.println(e); 
    } 

打印

A=99.5 
C=67.4 
B=67.4 
D=67.3 
+0

与equals的一致性当然是理想的,但并不总是需要TreeMap。根据文档,“即使排序与等号不一致,排序映射的行为也是明确定义的;它只是不服从Map接口的总体契约。” –

+0

我同意,将更正我的答案 –

0

亚当Crume的代码是非常重要的。为了更好地解释你,当你打电话给你的sorted_map.get(key)时,它会去java.util.TreeMap class',getEntryUsingComparator方法,因为你明确地设置了比较器。这种方法看起来像

final Entry<K,V> getEntryUsingComparator(Object key) { 
     K k = (K) key; 
     Comparator<? super K> cpr = comparator; 
     if (cpr != null) { 
      Entry<K,V> p = root; 
      while (p != null) { 
       int cmp = cpr.compare(k, p.key); 
       if (cmp < 0) 
        p = p.left; 
       else if (cmp > 0) 
        p = p.right; 
       else 
        return p; 
      } 
     } 
     return null; 
    } 

由于是在你自己的价值比较compare方法键相比,该条目将是无效,因此价值也将是零,因为map.get作为

public V get(Object key) { 
     Entry<K,V> p = getEntry(key); 
     return (p==null ? null : p.value); 
    } 
相关问题