java - 使 TreeMap 比较器容忍 null

标签 java sorting nullpointerexception comparator treemap

这个自定义的 Valuecomparator 按其值对 TreeMap 进行排序。但是在查找TreeMap是否有某个key的时候,不允许出现nullpointexception。我如何修改比较器以处理空点?

    import java.io.IOException;
    import java.util.Comparator;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.TreeMap;



    public class TestTreeMap {

        public static class ValueComparator<T> implements Comparator<Object> {

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

            @Override
            public int compare(Object a, Object b) {
                /*if (((Double) base.get(a) == null) || ((Double) base.get(b) == null)){
                    return -1;
                }   */      
                if ((Double) base.get(a) < (Double) base.get(b)) {
                    return 1;
                } else if ((Double) base.get(a) == (Double) base.get(b)) {
                    return 0;
                } else {
                    return -1;
                }
            }

        }

        public static void main(String[] args) throws IOException { 
            Map<String, Double> tm = new HashMap<String, Double>();
            tm.put("John Doe", new Double(3434.34)); 
            tm.put("Tom Smith", new Double(123.22)); 
            tm.put("Jane Baker", new Double(1378.00)); 
            tm.put("Todd Hall", new Double(99.22)); 
            tm.put("Ralph Smith", new Double(-19.08)); 

            ValueComparator<String> vc = new ValueComparator<String>(tm);
            TreeMap<String, Double> sortedTm = 
                    new TreeMap<String, Double>(vc);
            sortedTm.putAll(tm);

            System.out.println(sortedTm.keySet());
            System.out.println(sortedTm.containsKey("John Doe"));
            // The comparator doesn't tolerate null!!!
            System.out.println(!sortedTm.containsKey("Doe"));
        }


}

最佳答案

这不是火箭科学......

将此插入注释掉的代码的位置:

if (a == null) {
    return b == null ? 0 : -1;
} else if (b == null) {
    return 1;
} else 

这将 null 视为比任何非 null Double 实例更小的值。


您的版本不正确:

if ((a==null) || (b==null)) {return -1;}

这表示“如果 a 为 null 或 b 为 null,则 a 小于 b”。

这会导致像

这样的虚假关系
null < 1.0  AND 1.0 < null

null < null

当集合/映射中存在空值时,这种事情会导致树不变量中断,并导致不一致和不稳定的键排序......甚至更糟。

有效比较方法的要求javadocs中列出。 .数学版本是该方法必须定义一个 total order在所有可能输入值的域上。

关于java - 使 TreeMap 比较器容忍 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9597061/

相关文章:

java - 空指针异常,我不知道为什么

java - 在给出 NullPointerException 的 android Assets 中打开文本文件

Java获取工具提示信息

java - 声明 "=="条件的标准准则是什么?

python - 按键排序字典,然后按值排序(列表或元组?)

sorting - 按数字和字母顺序对基于结构的 slice 进行排序

java - android获取OnTouchEvent即使应用程序不活动,java空指针

java - 我为练习编写的代码有效吗?

java - 导出带有希伯来字符的 CSV,可由 Excel 打开

java - 对 Javascript 对象文字进行排序