Domanda

Sto convertendo un'applicazione per utilizzare Java 1.5 e ho trovato il seguente metodo:

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

Idealmente vorrei che il metodo prenda due comparabili dello stesso tipo, è possibile convertirlo e come?

Ho pensato che quanto segue avrebbe funzionato:

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

ma non è riuscito a eliminare un avviso in IntelliJ "Chiamata non selezionata a 'compareTo(T)' come membro del tipo non elaborato 'java.lang.Comparable'" sulla riga:

return o1.compareTo(o2);
È stato utile?

Soluzione

Cambialo in:

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

Ne hai bisogno perché Comparable è esso stesso un tipo generico.

Altri suggerimenti

Ecco un caso strano:

static class A {
    ...
}

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

Fortunatamente un codice come quello sopra è raro, ma nullCompare() non supporterà il confronto di B a meno che non venga indicato che Comparable può applicarsi a T o qualsiasi sua superclasse:

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

Anche se la maggior parte delle persone non trarrà mai beneficio dalla modifica di cui sopra, potrebbe tornare utile durante la progettazione di API per le librerie esportate.

Non posso modificare quindi devo pubblicare la mia risposta.

È necessario dichiarare il parametro di tipo annidato poiché Comparable è generico.

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

Tienilo presente Paragonabile< ?superT>, che rende più flessibile.Vedrai la stessa definizione del metodo su Collections.sort

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

Non sono sicuro che genericizzare questo metodo abbia senso.Attualmente il metodo funziona su qualsiasi tipo di Comparabile;se lo genericizzi dovrai implementarlo (esattamente con lo stesso codice) più volte.A volte è possibile confrontare due oggetti che non hanno un antenato comune e qualsiasi versione generica non lo consente.

Aggiungendo i generici non aggiungerai alcuna sicurezza al codice;eventuali problemi di sicurezza si verificheranno nella chiamata a compareTo.Quello che suggerirei è semplicemente di sopprimere l'avviso.In realtà non ti avverte di nulla di utile.

Per renderlo ancora più generale, potresti anche consentirgli di funzionare per due tipi diversi.=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);
    }
  }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top