2015-07-26 11 views
17

Sono nuovo per i generici. Puoi vedere che sto ripetendo del codice dopo aver conosciuto il tipo esatto di val, filterSmall, filterGreat. Voglio scrivere un codice generico per confrontare val con i valori del filtro. Potrei scrivere qualcosa di simileJava Codice generico

private <T> boolean compareAgainstFilters(T val, T filterSmall, T filterGreat) { 
    if (!(filterSmall != null && filterSmall <= val)) { 
     return true; 
    } 

    if (!(filterGreat != null && val <= filterGreat)) { 
     return true; 
    } 
    return true; 
} 

ma al momento della compilazione, Java non saprei se l'operatore <= è valido per il tipo T.

Non voglio ripetere il codice, quindi come posso ottenerlo?

if (value != null) { 
     switch (value.getClass().getName()) { 
     case "java.lang.Long": 
      Long filterSmall = (Long) filterSmaller; 
      Long filterGreat = (Long) filterGreater; 
      Long val = (Long) value; 

      if (!(filterSmall != null && filterSmall <= val)) { 
       return true; 
      } 

      if (!(filterGreat != null && val <= filterGreat)) { 
       return true; 
      } 
      break; 

     case "java.lang.Float": 
      Float filterSmallFloat = (Float) filterSmaller; 
      Float filterGreatFloat = (Float) filterGreater; 
      Float valFloat = (Float) value; 

      if (!(filterSmallFloat != null && filterSmallFloat <= valFloat)) { 
       return true; 
      } 

      if (!(filterGreatFloat != null && valFloat <= filterGreatFloat)) { 
       return true; 
      } 
     } 
    } 
+1

Penso che tu abbia un piccolo bug nella tua logica: ritorni 'true' se' val' è maggiore di 'filterSmall', anche se è maggiore di' filterGreat'. Inoltre, si restituisce 'true' se' val' è minore di 'filterGreat', anche se è minore di' filterSmall'. Infine, penso che tu voglia 'return false;' se nessuna delle clausole 'if' è' true'. – Turing85

+0

Qual è la domanda specifica per java 8? – the8472

+0

Non ero sicuro se ci potesse essere un modo migliore per risolvere questo in Java 8. Indovina. – Kaunteya

risposta

24

È possibile utilizzare l'interfaccia Comparable per il confronto dei numeri, poiché tutte le classi involucro di primitive numerici attuarla:

private <T extends Comparable<T>> boolean compareAgainstFilters(T val, T filterSmall, T filterGreat) { 
    if (!(filterSmall != null && filterSmall.compareTo(val)<=0)) { 
     return true; 
    } 

    if (!(filterGreat != null && val.compareTo(filterGreat)<=0)) { 
     return true; 
    } 
    return true; 
} 

<T extends Comparable<T>> limita i tipi che possono essere utilizzati come argomenti tipo anziché T. In questo caso sono tenuti a implementare Comparable<T>.

4

Non è possibile utilizzare gli operatori < o > nel metodo generico. Normalmente quando la variabile è di tipo Float o Long, il compilatore accetta l'operatore dopo aver eseguito la conversione automatica di unboxing (per ottenere il tipo primitivo) nel codice compilato. In altre parole,

filterSmall <= val 

viene compilato a:

filterSmall.longValue() <= val.longValue() 

Nel metodo generico, non v'è alcun modo per il compilatore di applicare conversione unboxing. L'unico modo per eseguire un confronto è che il parametro type estenda l'interfaccia Comparable e utilizzi il metodo compareTo. Si noti che i tipi Float, Long e così via implementano già questa interfaccia.