【问题标题】:Make TreeMap Comparator tolerate null使 TreeMap Comparator 容忍 null
【发布时间】:2012-03-24 17:16:59
【问题描述】:

这个自定义的 Valuecomarator 按它的值对 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"));
        }


}

【问题讨论】:

    标签: java sorting nullpointerexception comparator treemap


    【解决方案1】:

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

    在注释掉的代码处插入这个:

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

    这会将null 视为一个小于任何非空Double 实例的值。


    您的版本不正确:

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

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

    这会导致像

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

    当集合/映射中有空值时,这种事情会导致树不变量破坏,并导致键顺序不一致和不稳定......甚至更糟。

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

    【讨论】:

    • 啊,是的,让它小于非空!!!我试过if ((a==null) || (b==null)) {return -1;}。但这不能正确地对地图进行排序。为什么会这样?
    • 因为它违反了comparator.compare(x, x) == 0x.equals(x),特别是当x == null时的约束。
    猜你喜欢
    • 1970-01-01
    • 2013-11-03
    • 2021-11-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-06
    • 2011-10-07
    • 2012-01-19
    • 2012-05-09
    相关资源
    最近更新 更多