2009-05-27 3 views
5

Wir stellen einige der guten Sammelvorgänge für unsere Codebase vor, ohne eine neue externe Bibliotheksabhängigkeit hinzuzufügen. Wir fügen diese Methoden unserem Dienstprogrammpaket hinzu.Naming Collection Extensions zur besseren Übersicht

static public List<T> filter(List<T> source, Predicate<T> filter); 
static <Y,T> public List<Y> transform(List<T> source, Mutator<Y,T> filter); 
static public boolean exists(List<T> source, Predicate<T> filter); 
static public T findFirst(List<T> source, Predicate<T> filter); 
static public boolean trueForAll(List<T> source, Predicate<T> filter); 

mit den damit verbundenen Schnittstellen

public interface Predicate<T> { public boolean apply(T item); } 
public interface Mutator<T,Y> { public Y apply(T item); } 

So sind die Fragen:

  • Ist Filter einen guten Namen für die Klasse, um die Erweiterungen enthalten? Wenn nicht, ein besser?
  • Ist Mutator < T, Y> richtig benannt?
  • Soll ich lieber Karte-verwandeln und -Filter reduzieren?
  • Gibt es irgendwelche wichtigen set-based Funktionen, die ich vergessen habe, in die Bibliotheksklasse aufzunehmen?

Edited hinzuzufügen: Ein wesentliches Argument Ich habe gegen Karte (und damit für verwandeln) ist, dass Karte aufgrund der vielen Anwendungen für java.util.Map signifikante semantische Last hat

Antwort

1

Ich würde sie Karte und Filter nennen. Reduce hat eine etwas andere Bedeutung für mich und Transformation ist zu vage. Wie für den Klassennamen, Filter möglicherweise nicht die beste, aber ich habe keine bessere Empfehlung.

Ich weiß, dass Sie nicht für diese speziell gefragt wurden, aber einige der Unterschriften in den generischen Methoden verbessert werden kann:

static public <T> List<T> filter(List<T> source, Predicate<? super T> filter); 
static public <Y,T> List<Y> transform(List<T> source, Mutator<Y,? super T> filter); 
static public <T> boolean exists(List<T> source, Predicate<? super T> filter); 
static public <T> T findFirst(List<T> source, Predicate<? super T> filter); 
static public <T> boolean trueForAll(List<T> source, Predicate<? super T> filter); 
+0

Danke, da ich es gewohnt bin, in CLR-Generika und nicht in JDK5-Generika zu denken, ist das definitiv ein guter Punkt. –

0

Das ist nicht wirklich das, was Sie gefragt haben, aber es ist im Geiste Ihrer Frage. Für mich liest es besser zu sagen:

List<String> shortWords = filtered(allWords, short); 

als

List<String> shortWords = filter(allWords, short); 

Ich würde Stick mit und Filter verwandeln.

+1

Ich würde eher ablehnen; Ich denke, das Verb funktioniert ein wenig klarer als das Adjektiv (weil es genauer beschreibt die Tatsache, dass eine Aktion auftritt). Es ist jedoch eine kleine Meinungsverschiedenheit. –

+0

Ich neige dazu, Methoden als Aktionen zu betrachten. Filter scheint geeigneter als gefiltert. Das Wichtigste ist jedoch, konsequent zu sein. – ebrown

+0

Ich kann Ihre Argumentation verstehen, McWafflestix & ebrown, aber ich möchte eine Wert zurückgebende Funktion nennen, so dass es beschreibt, was zurückgegeben wird. Was zurückgegeben wird, ist die gefilterte Liste, es ist nicht der Filter. –

1

Das sieht wirklich gut aus; Ich denke du bist hier definitiv auf dem richtigen Weg. Ja, ich finde Mutator ist ein guter Name. transform ist besser, weil es häufiger als Verb gelesen wird, und map hat eine "Substantiv" -Konnotation, die verwirrend sein könnte; und die einzige hauptsächliche mengenbasierte Funktion, von der ich denken könnte, dass sie sie brauchen könnte, wäre eine Neuordnungsfunktion.

+0

Da Collections.sort verfügbar ist, dachte ich nicht, dass wir eine zusätzliche Sortiermethode benötigen. –

1

in einer ähnlichen Bibliothek, die ich verwenden:

  • Spezifikation anstelle von Prädikat: aSpecification.isSatisfiedBy(anObject);
  • Mapper anstelle von Mutator
  • Karte ist sammeln fo r Smalltalker (verwandeln in Ihrem Fall)
  • fach ist für Smalltalker injizieren
  • Filter ist wählen für Smalltalker
+0

falten? Was ist die zugrunde liegende Operation dort? –

+0

http://c2.com/cgi/wiki?FoldFunction – dfa

0

Es sollte Mutate sein Trans scheint (oder alternativ sollte Mutator Transformator sein,) der Konsistenz halber. Das scheint ziemlich klar über die Absicht:

static <Y,T> public List<Y> mutate (List<T> originalForm, Mutator<Y,T> mutator); 

Es ist auch ein bisschen ausführliche (aber konsequente und konventionell) spec:

static public boolean isTrueForAll(List<T> source, Predicate<T> filter); 

oder

static public boolean assertTrueForAll(List<T> source, Predicate<T> filter); 
+0

guter Punkt über isTrueForAll vs. trueForAll ... (aber ich muss zugeben, dass aus der "Was fehlt in JDK1.5 Sammlungen, die in der .Net BCL" Perspektive ist, so dass meine Benennung Erwartung eine bereits bestehende Voreingenommenheit hatte kommen. .. –

2

Sind Gibt es irgendwelche wichtigen Set-basierte Funktionen, die ich in vergessen habe in der Bibliotheksklasse enthalten?

Für übergeordnete Sammlungsfunktionen verwende ich den von Adrian Kuhn in seinem Artikel "Pimp My Foreach" beschriebenen Ansatz.

Einige davon haben Sie schon bekommen, aber dachte, ich würde sie es trotzdem werfen:

  • AllSatisfy
  • AnySatisfy
  • Cardinality
  • sammeln
  • Graf
  • CutPieces
  • Detect
  • Falten
  • GroupedBy
  • IndexOf
  • Inject
  • Ablehnen
  • Select