Независимо от скорости ваш компаратор неверен.
Единственное, что следует считать равным, - это, ну, в общем, равные вещи. В настоящее время вы могли бы считать, что null
равно "non-null"
, и это может привести к странному поведению.
В частности, вы, похоже, сравниваете первую пару соответствующих значений, которые оба не являются -ноль. Это нарушает требование транзитивности реализаций Comparator. Рассмотрим, например:
A = {"surname1": "A", "surname2", null, "name": "A"}
B = {"surname1": null, "surname2", "B", "name": "B"}
C = {"surname1": "A", "surname2", "C", "name": null}
Согласно вашему компаратору, A < B
и B < C
. Однако A == C
, что делает его недопустимым компаратором.
Самый простой способ написать этот компаратор - правильно - будет примерно так:
nullsLast(comparing(m -> (String) m.get("surname1")))
.thenComparing(nullsLast(comparing(m -> (String) m.get("surname2"))))
.thenComparing(nullsLast(comparing(m -> (String) m.get("name"))));
где nullsLast
и comparing
это методы из Comparator
. (Вместо этого можно использовать nullsFirst
, если вы предпочитаете обрабатывать значения NULL именно так).
С pre- Java 8 вы можете написать эквивалентное сравнение, используя вспомогательный метод:
public int compare(Map m1, Map m2) {
int lResult;
lResult = compare(m1, m2, "surname1");
if (lResult != 0) return lResult;
lResult = compare(m1, m2, "surname2");
if (lResult != 0) return lResult;
return compare(m1, m2, "name");
}
private int compare(Map m1, Map m2, String key) {
String v1= (String)m1.get(key);
String v2= (String)m2.get(key);
if (v1 != null && v2 != null) {
return v1.compareTo(v2);
}
return Boolean.compare(v1 != null, v2 != null);
}
Или используйте что-нибудь вроде Guava's ComparisonChain
.