Como simplificar uma implementação compareTo () com segurança nula?

Estou implementandocompareTo() método para uma classe simples como essa (para poder usarCollections.sort() e outros brindes oferecidos pela plataforma Java):

public class Metadata implements Comparable<Metadata> {
    private String name;
    private String value;

// Imagine basic constructor and accessors here
// Irrelevant parts omitted
}

eu quero oordenação natural para que esses objetos sejam: 1) classificados por nome e 2) classificados por valor se o nome for o mesmo; ambas as comparações não diferenciam maiúsculas de minúsculas. Para ambos os campos, os valores nulos são perfeitamente aceitáveis, portantocompareTo não deve quebrar nesses casos.

A solução que vem à mente é a seguinte: (estou usando "cláusulas de guarda" aqui, enquanto outros podem preferir um único ponto de retorno, mas isso não vem ao caso):

// 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);
}

Isso faz o trabalho, mas não estou perfeitamente feliz com esse código. É certo que não émuito complexo, mas é bastante detalhado e tedioso.

A questão é,como você faria isso menos detalhado (mantendo a funcionalidade)? Sinta-se à vontade para consultar as bibliotecas padrão Java ou o Apache Commons, se elas ajudarem. A única opção para tornar isso (um pouco) mais simples seria implementar meu próprio "NullSafeStringComparator" e aplicá-lo para comparar os dois campos?

Edições 1-3: Eddie está certo; Corrigido o caso "ambos os nomes são nulos" acima

Sobre a resposta aceita

Eu fiz essa pergunta em 2009, no Java 1.6, é claro, e na épocaa solução JDK pura de Eddie foi minha resposta aceita preferida. Eu nunca mudei para mudar isso até agora (2017).

Há tambémSoluções de bibliotecas de terceiros—Uma coleção Apache Commons 2009 e uma goiaba 2013, ambas postadas por mim — que eu preferia em algum momento.

Agora fiz a limpezaSolução Java 8 por Lukasz Wiktor a resposta aceita. Definitivamente, isso deve ser preferido no Java 8 e atualmente o Java 8 deve estar disponível para quase todos os projetos.

questionAnswers(16)

yourAnswerToTheQuestion