Java 8 Stream Tutorial część 1

Bardzo często używamy pętli for. Jest ona prosta, i wielu przypadkach w zupełności wystarczająca. Ale bardzo często wykonujemy w niej jeszcze dodatkowe operacje, często jakieś porównania, i wychodzi nam z tego dość skomplikowana struktura. Może można ją uprościć?

We use for loop a lot. It’s easy, and in many cases that’s all we need. But quite often we do many other things inside a loop, we make comparisons, another loops and so on. And it makes out code even more complicated. Can we simplify it?


Weźmy prosty przykład:

Chcemy pobrać parzyste liczby od 0 do 10
Standardowo moglibyśmy to zrobić tak:

Wszystko jest ok. Działa.
Ale czy jest to czytelne? Czy dodanie kolejnego jakiegoś warunku nie skomplikuje dodatkowo kodu?
A przecież można prościej:

Dzięki zastosowaniu streamów i dodaniu filtra udało się uprościć kod. A co jeśli z tych elementów chcielibyśmy stworzyć listę?

Krótka uwaga. We wszystkich przykładach używam biblioteki Guava – https://code.google.com/p/guava-libraries/
Bardzo dużo upraszcza, a o to przecież chodzi 🙂

W standardowym przypadku zrobilibyśmy to mniej więcej tak:

A ze stream?

Zauważcie metodę boxed()
Według dokumentacji Javy – http://docs.oracle.com/javase/8/docs/api/java/util/stream/IntStream.html#boxed–
IntStream nie może być po prostu zamieniony na listę, trzeba tego streama najpierw spakować do Integera, czyli zamienić na obiekt 🙂 Jeśli byłyby to zwykłe obiekty, nie byłoby potrzeby zastosowania tej metody, ale o tym za moment 🙂

Jeśli wiemy, że w danym kawałku kodu będziemy potrzebowali zawsze tylko elementów nieparzystych, to można powyższy kod jeszcze uprościć:

Zauważcie metodę limit(5) – aby nieparzyste inty nie tworzyły się w nieskończoność, za pomocą metody limit ograniczamy ilość wygenerowanych intów (w tym przypadku wygenerujemy 5 nieparzystych elementów).

Dzięki metodzie iterate możemy pisać już bardzo skomplikowane generatory liczb.

A co jeśli potrzebujemy mieć sumę wszystkich nieparzystych elementów?
To jest tak proste, że moja babcia by to potrafiła:

A może średnią?

A jak by to zrobić klasycznie? Można na pewno zrobić to na wiele sposobów…


Let’s take a simple example:

We want to take even numbers from 0 to 10
Normally, we could write something like this:

Everything is ok, all is working…

But is it readeable? Can we add another condition without complicating out code?
Here is another approach…

Thanks to Streams, and adding one filter, i’ve managed to make our code look completely different. And simpler.
What if we would like to add a list?
Without streams we would do something like:

With streams?

Take a look at boxed() method.

According to java doc –

Zauważcie metodę boxed() http://docs.oracle.com/javase/8/docs/api/java/util/stream/IntStream.html#boxed IntStream can’t be converted to a list, first, we must pack every element to Integer (object). If we would have objects from the begeining, there would be no use of this method.

We can also simplify this code, if we know, that we will only need odd elements.

Take a look at limit(5) method. Normally IntSteam will create our numbers indefinitely. With limit, we can stop it after creation of 5 elements.

Thanks to this method, we can write very complicated number generators

What if i need a sum of all odd numbers?
My grandmother could do it 🙂

What about avarage?

And how to do it in classical way? This is one of solutions:

»