2009-05-27 11 views
5

Wprowadzając część dobrodziejstw operacji zbierania danych do naszej bazy kodów bez dodawania nowej zależności od bibliotek zewnętrznych, dodajemy te metody do naszego pakietu narzędziowego.Przedłużanie kolekcji nazw dla większej przejrzystości

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

z towarzyszącymi interfejsów

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

tak więc pytania:

  • Czy Filtry dobre imię dla klasy zawierającej rozszerzenia? Jeśli nie, to lepiej?
  • Czy Mutator < T, Y> odpowiednio nazwany?
  • Wolałbym mapa do przekształcić i zmniejszyć do filtrem?
  • Czy są jakieś ważne funkcje oparte na zestawie, o których zapomniałem zawrzeć w klasie biblioteki?

Edited by dodać: znaczny argumentu mam przeciwko mapie (a tym samym na rzecz przekształcić) jest to, że mapa ma znaczny ładunek semantyczny powodu wielu zastosowań java.util.Map

Odpowiedz

1

Nazwałbym je mapa i filtr. Redukcja ma dla mnie nieco inne znaczenie, a transformacja jest zbyt ogólnikowa. Jeśli chodzi o nazwę klasy, Filtry mogą nie być najlepsze, ale nie mam lepszej rekomendacji.

wiem, że nie pytali o to specjalnie, ale niektóre z podpisami w metodach generycznych można poprawić:

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

Dzięki, że jestem przyzwyczajony do myślenia w generycznych kategoriach CLR, a nie generycznych JDK5, to zdecydowanie dobry punkt. –

0

To nie jest to, o co prosiłeś, ale jest zgodne z duchem twojego pytania. Dla mnie to brzmi lepiej powiedzieć:

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

niż

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

chciałbym trzymać przekształcić i filtr.

+1

bym raczej się nie zgadza; Myślę, że czasownik działa trochę jaśniej niż przymiotnik (ponieważ dokładniej opisuje to, że jakieś działanie ma miejsce). Jest to jednak drobny spór. –

+0

Zwykle uważam metody za działania. filtr wydaje się bardziej odpowiedni niż filtrowany. Ważną rzeczą jest być konsekwentnym. – ebrown

+0

Rozumiem twoje rozumowanie, McWafflestix i ebrown, ale chciałbym nazwać funkcję zwracającą wartość, aby opisała to, co jest zwracane. Zwrócona jest przefiltrowana lista, to nie jest filtr. –

1

To wygląda naprawdę ładnie; Myślę, że jesteś na dobrej drodze. Tak, myślę, że Mutator to dobre imię; transformacja jest lepsza, ponieważ jest częściej czytana jako czasownik, a mapa ma konotację "rzeczownikową", która może być myląca; a jedyną główną funkcją opartą na zestawach, którą mógłbym chcieć, byłaby funkcja zmiany kolejności.

+0

, ponieważ Collections.sort jest dostępny, nie sądziłem, że potrzebujemy dodatkowej metody sortowania. –

1

w podobny biblioteki użyłem:

  • Specyfikację zamiast Predicate: aSpecification.isSatisfiedBy(anObject);
  • Mapper zamiast mutator
  • mapa jest zbierać fo R smalltalkers (przekształcić w danym przypadku)
  • krotnie jest wstrzyknąć dla smalltalkers
  • filtracyjnych jest wybrać dla smalltalkers
+0

fold? jaka jest tam operacja? –

+0

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

0

Wydaje Transform powinien być mutować (lub alternatywnie mutator powinny być Transformer,) dla zachowania spójności. Wydaje się to dość oczywiste, o zamiarze:

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

Jest również nieco bardziej rozwlekły (ale bardziej spójne i konwencjonalna) do spec:

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

lub

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

dobry punkt o isTrueForAll vs. trueForAll ... (ale muszę przyznać, że przychodzę do tego z "tego, czego brakuje w kolekcjach JDK1.5, które jest obecne w perspektywie .Net BCL", więc moje oczekiwanie nazywania miało wcześniejsze uprzedzenia. .. –

2

Czy istnieją jakieś ważne funkcje oparte na ustawieniach, które zapomniałem o w klasie biblioteki?

Dla funkcji zbierania wyższego rzędu stosuję podejście opisane przez Adriana Kuhna w jego artykule "Pimp My Foreach".

Niektóre z nich już mam, ale pomyślałem, że wyrzucić tam i tak:

  • AllSatisfy
  • AnySatisfy
  • Relacja
  • Zbierz
  • Hrabia
  • CutPieces
  • Wykrywanie
  • Fold
  • GroupedBy
  • IndexOf
  • Inject
  • Odrzuć
  • Wybierz