Java:为什么我的输出结果是null?

3
public class A{

   TreeMap<String, Double> sortedPairList;
   HashMap<String, Double> PairList = new HashMap<String, Double>();

   public static void main(String[] args) {

   A p = new A();

    p.PairList.put("a00", 0.3920948902348);
    p.PairList.put("a01", 0.4920948902348);
    p.PairList.put("a02", 0.3420948902348);
    p.PairList.put("a03", 0.5920948902348);
    p.PairList.put("a04", 0.6720948902348);
    p.PairList.put("a05", 0.3940948902348);
    p.PairList.put("a06", 0.3920948902348);
    p.PairList.put("a07", 0.9920948902348);
    p.PairList.put("a08", 0.6920948902348);
    p.PairList.put("a09", 0.7920948902348);
    p.PairList.put("a10", 0.8820948902348);
    p.PairList.put("a11", 0.1220948902348);
    p.PairList.put("a12", 0.1920948902348);
    p.PairList.put("a13", 0.4520948902348);
    p.PairList.put("a14", 0.3434948902348);
    p.PairList.put("a15", 0.5690948902348);
    p.PairList.put("a16", 0.5920948902348);
    p.PairList.put("a17", 0.8920948902348);
    p.PairList.put("a18", 0.920948902348);
    p.PairList.put("a19", 0.9820948902348);
    p.PairList.put("a20", 0.1920948902348);
    p.PairList.put("a21", 0.5920948902348);
    p.PairList.put("a22", 0.3920948902348);
    p.PairList.put("a23", 0.3920948902348);

    p.sortPairList(p.PairList) ;

    for(String s : p.sortedPairList.keySet() ){
         System.out.println("key:: value: " + s + "  ::"+p.sortedPairList.get(s));
    }

}//end of main


public void sortPairList(HashMap<String, Double> pairlist) {
    ValueComparator comp = new ValueComparator(pairlist);

    sortedPairList = new TreeMap<String, Double>(comp);

    sortedPairList.putAll(pairlist);


}// end of sortedPredicatePairList

class ValueComparator implements Comparator<Object> {

    Map<String, Double> temp;

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

    public int compare(Object p1, Object p2) {

        if ((Double) temp.get(p1) < (Double) temp.get(p2)) {
            return 1;
        } else if ((Double) temp.get(p1) == (Double) temp.get(p2)) {
            return 0;
        } else {
            return -1;
        }

    }
}// end of class ValueComparator
}//end of classA

我得到的输出如下,为什么在重复的值中出现了null:
key:: value: a07 ::0.9920948902348
key:: value: a19 ::0.9820948902348
key:: value: a18 ::0.920948902348
key:: value: a17 ::0.8920948902348
key:: value: a10 ::0.8820948902348
key:: value: a09 ::0.7920948902348
key:: value: a08 ::0.6920948902348
key:: value: a04 ::0.6720948902348
key:: value: a03 ::0.5920948902348
key:: value: a21 ::null
key:: value: a16 ::null
key:: value: a15 ::0.5690948902348
key:: value: a01 ::0.4920948902348
key:: value: a13 ::0.4520948902348
key:: value: a05 ::0.3940948902348
key:: value: a06 ::0.3920948902348
key:: value: a23 ::0.3920948902348
key:: value: a22 ::0.3920948902348
key:: value: a00 ::null
key:: value: a14 ::0.3434948902348
key:: value: a02 ::0.3420948902348
key:: value: a12 ::0.1920948902348
key:: value: a20 ::null
key:: value: a11 ::0.1220948902348
4个回答

3

来自 Tree Map API:

请注意,排序映射(无论是否提供显式比较器)维护的顺序必须与等于关系一致,如果此排序映射要正确实现Map接口。(有关等于关系的精确定义,请参见Comparable或Comparator。)这是因为Map接口是根据equals操作定义的,但是映射使用其compareTo(或compare)方法执行所有键比较,因此通过该方法被视为相等的两个键,从排序映射的角度来看是相等的。

您的ValueComparator绝对不符合equals关系。

不知何故,p.sortedPairList.keySet()包含按照您的“ValueComparator”是“相等”的键,但您得到了重复键的null


但是我无法看到比较器中的错误,请具体告诉我比较器代码有什么问题? - lancelot
请查看 Tree Map API 的链接,并仔细阅读“Compare() inconsistent with Equals()”的含义。简而言之,您在 TreeMap 中的键是由 ValueComparator.compare() 方法“相等”的,但不是由 String.equals() 方法“相等”的。 - korifey

2

声明PairList如下:

HashMap<String, Double> PairList = new HashMap<String, Double>();

并将您的ValueComparator#compare方法更改为:

public int compare(Object p1, Object p2) {
   return temp.get(p1).compareTo(temp.get(p2));
}

更新 根据您的评论,请使用以下compare方法以升序获取所有24个元素:

public int compare(String p1, String p2) {
    if (temp.get(p1).doubleValue() < temp.get(p2).doubleValue())
        return 1;
    else if (temp.get(p1).doubleValue() == temp.get(p2).doubleValue())
        return p1.compareTo(p2);
    else
        return -1;
}

return temp.get(p1).compareTo(temp.get(p2)); 给我 降序 排列。 - anubhava
但是现在又出现了另一个问题,我无法获取重复的数值,只有单个值被打印出来。 - lancelot
它只打印了18个键值对,而不是24个。 - lancelot
请检查上面更新部分的代码,以获取所有24个元素按升序排列的结果。 - anubhava

0

问题出在你的比较器里。

在Java中,你不能使用==操作符来比较对象。这个操作符并不像你期望的那样工作。因此,为了比较你在地图中保存的双精度值,你必须调用doubleValue()方法。以下是我修改后能够正确工作的比较器版本。

    public int compare(Object p1, Object p2) {

        if (temp.get(p1).doubleValue() < temp.get(p2).doubleValue()) {
            return 1;
        } else if (temp.get(p1).doubleValue() == temp.get(p2).doubleValue()) {
            return 0;
        } else {
            return -1;
        }           
    }

0

这是因为您在比较器中使用了==符号进行比较。将其替换为equals()方法,应该就可以解决问题:

 public int compare(Object p1, Object p2) {

            if ((Double) temp.get(p1) < (Double) temp.get(p2)) {
                return 1;
            } else if (((Double) temp.get(p1)).equals((Double) temp.get(p2))) {
                return 0;
            } else {
                return -1;
            }

        }

但是现在出现了另一个问题,我无法获取重复的值,只能打印出单个值。 它只打印出18个键-值对,而不是24个。 - lancelot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接