Pergunta

Estou convertendo uma aplicação para usar Java 1.5 e encontrei o seguinte método:

  /**
   * Compare two Comparables, treat nulls as -infinity.
   * @param o1
   * @param o2
   * @return -1 if o1<o2, 0 if o1==o2, 1 if o1>o2
   */
  protected static int nullCompare(Comparable o1, Comparable o2) {
    if (o1 == null) {
      if (o2 == null) {
        return 0;
      } else {
        return -1;
      }
    } else if (o2 == null) {
      return 1;
    } else {
      return o1.compareTo(o2);
    }
  }

O ideal seria que o método pegasse dois Comparáveis ​​do mesmo tipo, é possível converter isso e como?

Achei que o seguinte resolveria o problema:

protected static <T extends Comparable> int nullCompare(T o1, T o2) {

mas não conseguiu se livrar de um aviso no IntelliJ "Chamada não verificada para 'compareTo(T)' como membro do tipo bruto 'java.lang.Comparable'" na linha:

return o1.compareTo(o2);
Foi útil?

Solução

Altere para:

protected static <T extends Comparable<T>> int nullCompare(T o1, T o2) {

Você precisa disso porque Comparable é em si um tipo genérico.

Outras dicas

Aqui está um caso estranho:

static class A {
    ...
}

static class B extends A implements Comparable<A> {
    public int compareTo(A o) {
        return ...;
    }
}

Felizmente, códigos como o acima são raros, mas nullCompare() não suportará comparação de Bs, a menos que seja declarado que Comparable pode ser aplicado a T ou qualquer superclasse dela:

protected static <T extends Comparable<? super T>> int nullCompare(T o1, T o2) {

Mesmo que a maioria das pessoas nunca se beneficie do ajuste acima, ele pode ser útil ao projetar APIs para bibliotecas exportadas.

Não é possível editar, então tenho que postar minha resposta.

Você precisa declarar o parâmetro de tipo aninhado, pois Comparable é genérico.

protected static <T extends Comparable<? super T>> int nullCompare(T o1, T o2) {

Por favor, note que Comparável< ?super-T >, o que torna mais flexível.Você verá a mesma definição de método em Collections.sort

public static <T extends Comparable<? super T>> void sort(List<T> list) {

Não tenho certeza se generalizar esse método faz sentido.Atualmente o método funciona em qualquer tipo de Comparável;se você generalizá-lo, terá que implementá-lo (exatamente com o mesmo código) várias vezes.Às vezes é possível comparar dois objetos que não possuem um ancestral comum, e qualquer versão genérica não permitirá isso.

Ao adicionar genéricos você não adicionará nenhuma segurança ao código;quaisquer problemas de segurança ocorrerão na chamada para compareTo.O que eu sugeriria é simplesmente suprimir o aviso.Na verdade, não está avisando sobre nada útil.

Para torná-lo ainda mais geral, você pode até permitir que funcione para dois tipos diferentes.=P

  /**
   * Compare two Comparables, treat nulls as -infinity.
   * @param o1
   * @param o2
   * @return -1 if o1&lt;o2, 0 if o1==o2, 1 if o1&gt;o2
   */
  protected static <T> int nullCompare(Comparable<? super T> o1, T o2) {
    if (o1 == null) {
      if (o2 == null) {
        return 0;
      } else {
        return -1;
      }
    } else if (o2 == null) {
      return 1;
    } else {
      return o1.compareTo(o2);
    }
  }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top