См. Нижнюю часть этого ответа для обновленного (2013) решения, использующего Guava.
Это то, с чем я в конечном итоге пошел. Оказалось, что у нас уже есть служебный метод для сравнения нулевых строк, поэтому самым простым решением было использовать его. (Это большая кодовая база; легко пропустить такие вещи:)
public int compareTo(Metadata other) {
int result = StringUtils.compare(this.getName(), other.getName(), true);
if (result != 0) {
return result;
}
return StringUtils.compare(this.getValue(), other.getValue(), true);
}
Вот как определяется помощник (он перегружен, так что вы также можете определить, будут ли значения NULL первыми или последними, если хотите):
public static int compare(String s1, String s2, boolean ignoreCase) { ... }
Так что, по сути, это то же самое, что и ответ Эдди (хотя я бы не назвал метод статического помощника компаратором ) и ответ Ужина .
В любом случае, я бы вообще одобрил решение Патрика , так как я думаю, что по возможности рекомендуется использовать установленные библиотеки. ( Знайте и используйте библиотеки , как говорит Джош Блох.) Но в этом случае это не дало бы самый чистый и простой код.
Edit (2009): версия Apache Commons Collections
Собственно, вот способ упростить решение на основе Apache Commons NullComparator
. Объедините его с регистронезависимым Comparator
, представленным в String
классе:
public static final Comparator<String> NULL_SAFE_COMPARATOR
= new NullComparator(String.CASE_INSENSITIVE_ORDER);
@Override
public int compareTo(Metadata other) {
int result = NULL_SAFE_COMPARATOR.compare(this.name, other.name);
if (result != 0) {
return result;
}
return NULL_SAFE_COMPARATOR.compare(this.value, other.value);
}
Теперь это довольно элегантно, я думаю. (Остается только одна небольшая проблема: Commons NullComparator
не поддерживает генерики, поэтому есть непроверенное назначение.)
Обновление (2013): версия Guava
Почти 5 лет спустя, вот как я решил свой первоначальный вопрос. Если бы я писал код на Java, я бы (конечно) использовал Гуава . (И, конечно, не Apache Commons.)
Поместите эту константу куда-нибудь, например. в классе "StringUtils":
public static final Ordering<String> CASE_INSENSITIVE_NULL_SAFE_ORDER =
Ordering.from(String.CASE_INSENSITIVE_ORDER).nullsLast(); // or nullsFirst()
Затем в public class Metadata implements Comparable<Metadata>
:
@Override
public int compareTo(Metadata other) {
int result = CASE_INSENSITIVE_NULL_SAFE_ORDER.compare(this.name, other.name);
if (result != 0) {
return result;
}
return CASE_INSENSITIVE_NULL_SAFE_ORDER.compare(this.value, other.value);
}
Конечно, это почти идентично версии Apache Commons (оба используют
JDK CASE_INSENSITIVE_ORDER ), использование nullsLast()
- единственная вещь, специфичная для Гуавы. Эта версия предпочтительна просто потому, что Guava предпочтительнее, чем сборники Commons Collections. (Как все согласны .)
Если вам интересно узнать о Ordering
, обратите внимание, что он реализует Comparator
. Это очень удобно, особенно для более сложных задач сортировки, позволяя вам, например, объединить несколько заказов, используя compound()
. Прочитайте Заказ объяснил для более!