Java 对地图进行排序<;字符串,对象>;首先在Object.property1上,然后针对每个Object.property1,按Object.property2排序

Java 对地图进行排序<;字符串,对象>;首先在Object.property1上,然后针对每个Object.property1,按Object.property2排序,java,sorting,collections,Java,Sorting,Collections,我使用了下面的方法,首先在Object.property1上对贴图进行排序,然后对每个Object.property1按Object.property2进行排序 比如说, 属性1=出租车号码和 property2=提供者名称 我只是想知道这可以用一种更短更精确的方式来完成。如有任何帮助或建议,将不胜感激 private List<TestObject> sortByValue(final Map m) { List<TestObject> valu

我使用了下面的方法,首先在Object.property1上对贴图进行排序,然后对每个Object.property1按Object.property2进行排序

比如说,

属性1=出租车号码和
property2=提供者名称

我只是想知道这可以用一种更短更精确的方式来完成。如有任何帮助或建议,将不胜感激

    private List<TestObject> sortByValue(final Map m) {
        List<TestObject> values = new ArrayList<TestObject>();
        values.addAll(m.values());

        // First sort the list by Tax ID.
        Collections.sort(values, new Comparator<TestObject>() {
            public int compare(TestObject r1, TestObject r2) {
                Long taxId1 = (r1 == null ? null : r1.getTaxIdNumber());
                Long taxId2 = (r2 == null ? null : r2.getTaxIdNumber());

                if (taxId1 == null || taxId2 == null) {
                    return 0;
                }

                return taxId1.compareTo(taxId2);
            }
        });

        // Then sort the list by Provider name.
        Collections.sort(values, new Comparator<TestObject>() {
            public int compare(TestObject r1, TestObject r2) {
                String name1 = (r1 == null ? null : r1.getProviderName());
                String name2 = (r2 == null ? null : r2.getProviderName());

                if (name1 == null || name2 == null) {
                    return 0;
                }

                if (r1.getTaxIdNumber() == r2.getTaxIdNumber()) {
                    return name1.compareTo(name2);
                } else {
                    return 0;
                }
            }
        });

        return values;
    }
私有列表排序值(最终映射m){
列表值=新的ArrayList();
values.addAll(m.values());
//首先按税号对列表进行排序。
Collections.sort(值,新的Comparator(){
公共int比较(TestObject r1、TestObject r2){
Long-taxId1=(r1==null?null:r1.getTaxIdNumber());
Long-taxId2=(r2==null?null:r2.getTaxIdNumber());
如果(taxId1==null | | taxId2==null){
返回0;
}
返回taxId1.比较(taxId2);
}
});
//然后按提供者名称对列表进行排序。
Collections.sort(值,新的Comparator(){
公共int比较(TestObject r1、TestObject r2){
字符串名称1=(r1==null?null:r1.getProviderName());
字符串名称2=(r2==null?null:r2.getProviderName());
if(name1==null | | name2==null){
返回0;
}
if(r1.getTaxIdNumber()==r2.getTaxIdNumber()){
返回name1.compareTo(name2);
}否则{
返回0;
}
}
});
返回值;
}

您只需要一个比较器。首先比较一下出租车。如果它们是不等回报-1或1(视情况而定)。如果它们相等,则比较提供者名称

比如:

Collections.sort(values, new Comparator<TestObject>() {
        public int compare(TestObject r1, TestObject r2) {
            Long taxId1 = (r1 == null ? null : r1.getTaxIdNumber());
            Long taxId2 = (r2 == null ? null : r2.getTaxIdNumber());

            if (taxId1 == null || taxId2 == null) {
                return 0;
            }

            int cmp = taxId1.compareTo(taxId2);

            if (cmp != 0)
                return cmp;

            String name1 = (r1 == null ? null : r1.getProviderName());
            String name2 = (r2 == null ? null : r2.getProviderName());

            if (name1 == null || name2 == null) {
                return 0;
            }

            return name1.compareTo(name2);
        }
    });
Collections.sort(值,新比较器(){
公共int比较(TestObject r1、TestObject r2){
Long-taxId1=(r1==null?null:r1.getTaxIdNumber());
Long-taxId2=(r2==null?null:r2.getTaxIdNumber());
如果(taxId1==null | | taxId2==null){
返回0;
}
int cmp=taxId1。与(taxId2)相比;
如果(cmp!=0)
返回cmp;
字符串名称1=(r1==null?null:r1.getProviderName());
字符串名称2=(r2==null?null:r2.getProviderName());
if(name1==null | | name2==null){
返回0;
}
返回name1.compareTo(name2);
}
});

您的null处理违反了
compare
的约定,因为您认为
null
等于任何其他值,而JavaDoc写入:

比较其两个参数的顺序。返回负整数、零或正整数,因为第一个参数小于、等于或大于第二个参数

特别是:

最后,实现者必须确保
compare(x,y)==0
意味着
sgn(compare(x,z))
=
sgn(compare(y,z))
对于所有z

对于
x=null
y=“a”
z=“b”
,您的代码无法完成此任务

因此,如果列表中的任何对象或属性为
null
,则列表可能无法正确排序

尽管如此,我想知道列表是否真的包含
null
值或属性?如果没有,我将删除所有
null
检查,并以

Collections.sort(list, new Comparator<TestObject>() {
    @Override public int compare(TestObject o1, TestObject o2) {
        int c = o1.getTaxIdNumber().compareTo(o2.getTaxIdNumber);
        if (c != 0) {
            return c;
        }
        return o1.getProviderName().compareTo(o2.getProviderName());
    }
}
现在,这是一段相当重复和棘手的代码,这就是为什么Apache的同事们编写了。使用该API,您只需编写:

@Override int compare(TestObject r1, TestObject r2) {
    // insert null checks for r1 and r2 here - if you really need them

    return new CompareToBuilder()
        .append(r1.getTaxIdNumber(), r2.getTaxIdNumber())
        .append(r1.getProviderName(), r2.getProviderName())
        .toComparison();
    }
}

您希望它主要按TaxIdNumber排序,其次按提供者名称排序?是的,Brian。这就是目的,谢谢。。是的,这就是我在了解意图后要建议的:)
如果(taxId1==null | | taxId2==null){return 0;}
与equals不兼容(即
如果(taxId1==null&&taxId2!=null)
,它们不相等,但比较器返回0。
@Override int compare(TestObject r1, TestObject r2) {
    // insert null checks for r1 and r2 here - if you really need them

    return new CompareToBuilder()
        .append(r1.getTaxIdNumber(), r2.getTaxIdNumber())
        .append(r1.getProviderName(), r2.getProviderName())
        .toComparison();
    }
}