2015-07-26 11 views
17

Ich bin neu bei Generika. Sie können sehen, dass ich einen Code wiederhole, nachdem ich den genauen Typ von val, filterSmall, filterGreat gekannt habe. Ich möchte generischen Code für den Vergleich val gegen Filterwerte schreiben. Ich könnte so etwas wie dieseJava Generic Code

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

aber bei der Kompilierung schreiben, java würde nicht wissen, ob der <= Operator für Typen T gültig ist.

Ich möchte den Code nicht wiederholen, also wie kann ich das erreichen?

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

Ich denke, Sie haben einen kleinen Fehler in Ihrer Logik: Sie geben 'true' zurück, wenn' val' größer ist als 'filterSmall', auch wenn es größer als' filterGreat' ist. Außerdem geben Sie 'true' zurück, wenn' val' kleiner als 'filterGreat' ist, auch wenn es kleiner ist als' filterSmall'. Schließlich denke ich, dass du "falsch" zurückgeben willst, "wenn" if "-Klauseln" wahr "sind. – Turing85

+0

Wie ist Ihre Frage spezifisch für Java 8? – the8472

+0

Ich war mir nicht sicher, ob es in Java 8 einen besseren Weg zur Lösung geben könnte. Vermute nicht. – Kaunteya

Antwort

24

können Sie verwenden, um die Comparable Schnittstelle für Zahlen zu vergleichen, da alle Wrapper-Klassen von numerischen Primitiven sie implementieren:

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>> schränkt die Typen, die als Typ Argumente verwendet werden kann anstelle von T. In diesem Fall müssen sie Comparable<T> implementieren.

4

Sie können die Operatoren < oder > nicht in der generischen Methode verwenden. Normalerweise, wenn die Variable vom Typ Float oder Long ist, würde der Compiler den Operator akzeptieren, nachdem er eine automatische Unboxing-Konvertierung (um den primitiven Typ zu erhalten) im kompilierten Code ausgeführt hat. Mit anderen Worten,

filterSmall <= val 

zu kompiliert wird:

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

In dem allgemeinen Verfahren gibt es keine Möglichkeit für den Compiler Unboxing Umwandlung anzuwenden. Die einzige Möglichkeit, einen Vergleich durchzuführen, besteht darin, dass der Parameter type die Schnittstelle Comparable erweitert und die Methode compareTo verwendet. Beachten Sie, dass die Typen Float, usw. diese Schnittstelle bereits implementieren.