2014-12-12 13 views
5

Podoba mi się pomysł intermediate operations z Java8, gdzie wszystkie operacje zostaną zastosowane jeden raz, gdy zostanie osiągnięty terminal operation.Kolekcja bibliotek operacji pośrednich w języku Java7

Pytam, czy istnieje biblioteka, której mogę użyć z Java 7, która pozwoli mi osiągnąć takie zachowanie.

Uwaga:
Używam commons-collections4 dla operacji zbierania, jak forAllDo, więc możliwe jest wykorzystanie go do takiej sytuacji? (Związek pośredni vs operacji końcowych)

Odpowiedz

9

Guava

W miarę [Guava] znacznika wskazuje, większość operacji zbierania Guava leniwe - są stosowane tylko raz w razie potrzeby. Na przykład:

List<String> strings = Lists.newArrayList("1", "2", "3"); 
List<Integer> integers = Lists.transform(strings, new Function<String, Integer>() { 
    @Override 
    public Integer apply(String input) { 
     System.out.println(input); 
     return Integer.valueOf(input); 
    } 
}); 

Kod ten wydaje się przekonwertować List<String> Do List<Integer> jednocześnie pisząc struny do wyjścia. Ale jeśli faktycznie go uruchomisz, to nic nie da. Dodajmy jeszcze trochę kodu:

for (Integer i : integers) { 
    // nothing to do 
} 

Teraz zapisuje dane wejściowe!

To dlatego, że metoda Lists.transform() nie dokonuje transformacji, ale zwraca specjalnie spreparowaną klasę, która oblicza wartości tylko wtedy, gdy są potrzebne.

Dowód bonusu, że wszystko działa poprawnie: jeśli usunęliśmy pustą pętlę i zastąpiliśmy ją np. po prostu integers.get(1);, to faktycznie wypisze tylko numer 2.

Jeśli chcesz połączyć wiele metod jednocześnie, zawsze jest FluentIterable. To zasadniczo pozwala na kodowanie w stylu Java 8 Stream-like.


Goldman Sachs Kolekcje

Podczas Guava zwykle robi słusznie domyślnie pracuje z klas JDK, czasami trzeba coś bardziej skomplikowane. Tam właśnie pojawiają się kolekcje Goldman Sachs. Kolekcje GS dają o wiele więcej elastyczności i mocy dzięki kompletnemu ramu kolekcji ze wszystkim, o czym możesz marzyć. Lenistwo nie jest domyślnie, ale można go łatwo osiągnąć:

FastList<String> strings = FastList.newListWith("1", "2", "3"); 
LazyIterable<Integer> integers = strings.asLazy().collect(new Function<String, Integer>() { 
    @Override 
    public Integer valueOf(String string) { 
     System.out.println(string); 
     return Integer.valueOf(string); 
    } 
}); 

Znowu nic nie robi. Ale:

for (Integer i : integers) { 
    // nothing to do 
} 

nagle wyprowadza wszystko.

+4

P.S. W prawdziwym świecie, gdybym musiał przekonwertować 'List ' na 'List ', użyłbym '' 'Ints.stringConverter()' (http://docs.guava-libraries.googlecode.com /git-history/release/javadoc/com/google/common/primitives/Ints.html#stringConverter%28%29) jako funkcja transformująca. –