Вы можете оптимизировать немного. YMMV как читаемый код превосходит незначительную оптимизацию:
лизуюcompareTo()
метод для простого класса, такого как этот (чтобы иметь возможность использоватьCollections.sort()
и другие вкусности, предлагаемые платформой Java):
public class Metadata implements Comparable<Metadata> {
private String name;
private String value;
// Imagine basic constructor and accessors here
// Irrelevant parts omitted
}
Я хочуестественный порядок чтобы эти объекты были: 1) отсортированы по имени и 2) отсортированы по значению, если имя совпадает; оба сравнения должны быть без учета регистра. Для обоих полей нулевые значения вполне приемлемы, поэтомуcompareTo
не должен ломаться в этих случаях.
Решение, которое приходит на ум, заключается в следующем (я использую «пункты охраны» здесь, в то время как другие могут предпочесть одну точку возврата, но это не относится к делу):
// primarily by name, secondarily by value; null-safe; case-insensitive
public int compareTo(Metadata other) {
if (this.name == null && other.name != null){
return -1;
}
else if (this.name != null && other.name == null){
return 1;
}
else if (this.name != null && other.name != null) {
int result = this.name.compareToIgnoreCase(other.name);
if (result != 0){
return result;
}
}
if (this.value == null) {
return other.value == null ? 0 : -1;
}
if (other.value == null){
return 1;
}
return this.value.compareToIgnoreCase(other.value);
}
Это делает работу, но я не совсем доволен этим кодом. По общему признанию это неочень сложный, но довольно многословный и утомительный.
Вопрос в том,как бы вы сделали это менее многословным (при сохранении функциональности)? Не стесняйтесь обращаться к стандартным библиотекам Java или Apache Commons, если они помогают. Будет ли единственный вариант сделать это (немного) проще - реализовать мой собственный "NullSafeStringComparator" и применить его для сравнения обоих полей?
Редактирует 1-3: Эдди прав; исправлен вышеупомянутый случай "оба имени нулевые"
О принятом ответеЯ задал этот вопрос еще в 2009 году, на Java 1.6, конечно, и в то времячистое решение JDK от Eddie был мой предпочтительный принятый ответ. Я никогда не удосужился изменить это до сих пор (2017).
Это такжеСторонние библиотечные решения- одна из коллекций Apache Commons 2009 года и одна гуавы 2013 года, обе опубликованы мной, - которые я предпочел в какой-то момент времени.
Я сейчас сделала чистуюРешение Java 8 от Лукаша Виктора принятый ответ. Это определенно должно быть предпочтительным, если на Java 8, и в наши дни Java 8 должна быть доступна почти для всех проектов.