2008-12-15 14 views
5

ich über so etwas wie dieses denke:Was ist der beste Weg, um Min- und Max-Werte aus einer Liste von Vergleichen zu erhalten, in denen main Nullwerte enthält?

public static <T extends Comparable<T>> T minOf(T...ts){   
    SortedSet<T> set = new TreeSet<T>(Arrays.asList(ts)); 
    return set.first(); 
} 

public static <T extends Comparable<T>> T maxOf(T...ts){ 
    SortedSet<T> set = new TreeSet<T>(Arrays.asList(ts)); 
    return set.last(); 
} 

aber nicht null ist sicher, das auch etwas, was ich will, ist.

Kennen Sie einen besseren Weg, um dieses Problem zu lösen?

EDIT:

Nach den Kommentaren habe ich auch versucht min():

public static <T extends Comparable<T>> T minOf(T...ts){   
    return Collections.min(Arrays.asList(ts), new Comparator<T>(){ 

     public int compare(T o1, T o2) { 
      if(o1!=null && o2!=null){ 
       return o1.compareTo(o2); 
      }else if(o1!=null){ 
       return 1; 
      }else{ 
       return -1; 
      } 
     }}); 
} 

Was halten Sie davon?

+0

Das ist ineffizient, da Sie O benötigen (n log n) vergleicht, da die TreeSet effektiv die Sammlung sortiert, wobei n genügen vergleicht. Außerdem erstellen Sie viel unnötigen Müll (Arrays.asList erstellt eine Kopie von "ts", und das TreeSet ist auch nicht leicht). – mfx

+0

Arrays.asList erstellt keine Kopie des Arrays. –

+0

Ja, das würde funktionieren, aber warum nicht erklären und den Komparator sonst nennen, wo so wiederverwendbar? Rufen Sie dann, anstatt diese minOf-Funktion zu verwenden, einfach den Standard Collections.min mit dem genannten Komparator auf. Ihr Code wird durch Verwendung von Standardbibliotheksaufrufen deutlich lesbarer. – Pyrolistical

Antwort

39

Was ist los mit Collections.max?

Und warum kümmern Sie sich um Null-Sicherheit? Möchtest du wirklich Nullen in deiner Sammlung zulassen?

+0

Die Frage war für max * und * min. Collections.max() wird jedes Element betrachten. Dann macht Collections.min() wieder jedes Element zu sehen. Vielleicht ist das Sortieren nur einmal schneller. – Yetti99

+1

@ Yetti99 Sortierung wird langsamer sein, weil es "O (n log n)" und "max" + "min" ist "O (2n)". Was ein bisschen besser wäre, ist eine einzelne Schleife zu machen und Max und Min darin zu aktualisieren. Und das OP scheint nicht beides in einer einzigen Funktion zu erfordern. –

3

Wenn Sie wirklich "Null" aus dem Ergebnis ausschließen müssen, und Sie können nicht verhindern, dass es in Ihrem Array ist, dann sollten Sie vielleicht einfach durch das Array mit einer einfachen Schleife durchlaufen und den "min "und" max "in separaten Variablen. Sie können weiterhin die "compare()" - Methode für jedes Objekt verwenden, um es mit Ihren aktuellen "min" - und "max" -Werten zu vergleichen. Auf diese Weise können Sie Ihren eigenen Code hinzufügen, um nach Nullen zu suchen und sie zu ignorieren.

EDIT: hier ist ein Code, um zu illustrieren, worüber ich spreche. Leider gibt es einen Randfall, den Sie beachten müssen - was ist, wenn alle Argumente, die übergeben werden, null sind? Was gibt Ihre Methode zurück?

public static <T extends Comparable<T>> T minOf(T...ts){ 
    T min = null; 
    for (T t : ts) { 
     if (t != null && (min == null || t.compareTo(min) < 0)) { 
      min = t; 
     } 
    } 
    return min; 
} 

public static <T extends Comparable<T>> T maxOf(T...ts){ 
    T max = null; 
    for (T t : ts) { 
     if (t != null && (max == null || t.compareTo(max) > 0)) { 
      max = t; 
     } 
    } 
    return max; 
} 
1

Sie sollte Comparable nicht implementieren null zu akzeptieren, wie es der Vertrag des Interface bricht.

Von https://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html:

Beachten Sie, dass null ist keine Instanz einer Klasse, und e.compareTo (null) sollte eine Nullpointer obwohl e.equals (null) gibt false zurück zu werfen.

Sie müssen stattdessen eine neue Schnittstelle erstellen, z. ComparableNull stattdessen. auch

Siehe: