Sunteți pe pagina 1din 27

1

Prezentare 17:
Streams –
operatii

PROGRAMARE ORIENTATA
OBIECT
2020
Utilizare streams

 Map
 aplicarea unei functii fiecarui element al stream-ului

List<String> numeFeluri = meniu.stream()


.map(Fel::getNume)
.collect(toList());

List<String> cuvinte = Arrays.asList(“streams”, “in”, “java”);


List<Integer> lungCuvinte = cuvinte.stream()
.map(String::length)
.collect(toList());

22.01.2021 POO 2
Utilizare streams

 Aplatizare streams
Exemplu – lista caracterelor unice pentru o lista de cuvinte [“streams”,
“in”, “java”] -> [“s,” ”t,” ”r,” “e,” “a,” “m,” “I,” “n,” “j,” “v”]

Varianta 1:
cuvinte.stream()
.map(cuvant -> cuvant.split(“ ”) map(cuvant -> cuvant.split(“ ”) => Stream<String[]>
.distinct() distinct() => Stream<String[]>
.collect(toList()); collect(toList()) => List<String[]>

!!!! Se obtine List<String[]>, vrem List<String>

22.01.2021 POO 3
Utilizare streams

Varianta 2: Arrays.stream()

String[] arrayCuvinte = {“limbajul”, “java”};


Stream<String> streamCuvinte = Arrays.stream(arrayCuvinte);

cuvinte.stream()
.map(cuvant -> cuvant.split(“ ”) converteste fiecare cuvant intr-un
array de litere individuale
.map(Arrays::stream)
.distinct()
.collect(toList());
transforma fiecare array
intr-un stream

!!!! Se obtine List<Stream<String>>, vrem List<String>


22.01.2021 POO 4
Utilizare streams

Solutie: flatMap
cuvinte.stream()
.map(cuvant -> cuvant.split(“ ”) converteste fiecare cuvant intr-un
array de litere individuale
.flatMap(Arrays::stream)
.distinct()
.collect(toList());

transforma fiecare stream


generat intr-un singur stream

22.01.2021 POO 5
Utilizare streams

 Exemplu – fie o lista de numere => lista patratelor numerelor

List<Integer> numere = Arrays.asList(1, 2, 3, 4, 5);


List<Integer> patrate = numere.stream()
.map(n - > n*n)
.collect(toList());

 Exemplu – fie doua liste de numere => lista tuturor perechilor de


numere din cele doua liste:
[1, 2, 3], [3, 4] => [1, 3], [1, 4], [2, 3], [3, 4], [3, 3], [3, 4]

22.01.2021 POO 6
Utilizare streams

List<Integer> numere1 = Arrays.asList(1, 2, 3);


List<Integer> numere2 = Arrays.asList(3, 4);

List<int[]> perechi = numere1.stream()


.flatMap(i -> numere2.stream()
.map(j - > new int[]{i, j})
)
.collect(toList());

22.01.2021 POO 7
Utilizare streams

 Potrivire si regasire
 Potrivire

 anyMatch – exista un element in stream care satisface predicatul


dat?
if (meniu.stream().anyMatch(Fel::eVegetarian)) {
System.out.println(“Meniul poate fi agreat de vegetarieni”);
}
anyMatch intoarce un boolean => operatie finala
 allMatch – satisfac toate elementele stream-ului predicatul dat?
boolean eSanatos = meniu.stream()
.allMatch(fel -> fel.getCalorii() < 1000)
22.01.2021 POO 8
Utilizare streams

 noneMatch – niciun element al stream-ului nu satisface predicatul dat?

boolean eSanatos = meniu.stream()


.noneMatch(fel -> fel.getCalorii() >= 1000);

Operatiile anyMatch, allMatch, noneMatch folosesc short-circuiting, varianta


pentru streams a operatorilor &&, || din Java

22.01.2021 POO 9
Utilizare streams

 Gasirea unui element


 findAny – intoarce un element arbitrar din stream-ul curent

Exemplu – gasirea unui fel de mancare vegetarian

Optional<Fel> fel = meniu.stream()


.filter(Fel::eVegetarian)
.findAny();

22.01.2021 POO 10
Utilizare streams

Optional<T> (java.util.Optional) – clasa care reprezinta existenta sau


absenta unei valori
• isPresent() – true daca Optional contine o valoare, false altfel
• ifPresent(Consumer<T> bloc) – executa blocul daca o valoare
este prezenta
• T get() – intoarce valoarea daca exista, altfel arunca
NoSuchElementException
• T orElse(T other) - intoarce valoarea daca este prezenta, altfel
intoarce o valoare implicita

22.01.2021 POO 11
Utilizare streams

meniu.stream()
.filter(Fel::eVegetarian)
.findAny(); intorce Optional<Fel>
.ifPresent(fel -> System.out.println(fel.getNume());

daca o valoare este


gasita, este tiparita;
altfel nu se intampla
nimic

22.01.2021 POO 12
Utilizare streams

 Gasirea primului element


 findFirst – gaseste primul element care satisface un predicat

List<Integer> numere = Arrays.asList(1, 2, 3, 4, 5);


Optional<Integer> primulPatratDivCuTrei =
numere.stream()
.map(n -> n*n)
.filter(n -> n%3 == 0)
.findFirst(); //9

22.01.2021 POO 13
Utilizare streams

 Reducere – un stream este redus la o valoare


 Adunarea elementelor

int suma = 0; Int produs = 1;


for (int x: numere) for (int x: numere)
produs *= x;
suma += x;

int suma = numere.stream().reduce(0, (a, b) -> a + b);

int suma = numere.stream().reduce(0, Integer::sum);

Optional<Integer> suma = numere.stream().reduce((a,b) -> (a+b));

22.01.2021 POO 14
Utilizare streams

 Maxim si minim

Optional<Integer> max = numere.stream().reduce(Integer::max);

Optional<Integer> min = numere.stream().reduce(Integer::min);

22.01.2021 POO 15
Utilizare streams

Exemplu – numarul de feluri din meniu utilizand map si reduce

int numarFeluri = meniu.stream()


.map(f -> 1)
.reduce(0, (a, b) - > a + b);

22.01.2021 POO 16
Utilizare streams

 Stream-uri numerice
Exemplu - calculul numarului de calorii dintr-un meniu

int calorii = meniu.stream()


.map(Fel::getCalorii)
.reduce(0, Integer::sum);

Ideal:

int calorii = meniu.stream()


.map(Fel::getCalorii)
.sum();

22.01.2021 POO 17
Utilizare streams

 Streams asociate cu tipuri primitive – IntStream, DoubleStream, LongStream


 maparea la un stream numeric - mapToInt, mapToDouble, mapToLong

int calorii = meniu.stream() stream de feluri de mancare


.maptoInt(Fel::getCalorii)
.sum();
intoarce un IntStream

 conversia unui stream numeric la un stream de obiecte


IntStream intStream = meniu.stream().maptoInt(Fel::getCalorii);
Stream<Integer> stream = intStream.boxed();

22.01.2021 POO 18
Utilizare streams

 Valori implicite – OptionalInt, OptionalDouble, OptionalLong

OptionalInt maxCalorii = meniu.stream()


.mapToInt(Fel::getCalorii)
.max();
int max = maxCalorii.orElse(1); maxim implicit daca nu
exista nicio valoare

22.01.2021 POO 19
Utilizare streams

 Intervale numerice
 range, rangeClosed

IntStream numerePare = IntStream.rangeClosed(1, 100)


stream-ul numerelor
.filter(n -> n%2 == 0);
pare de la 1 la 100

System.out.println(numerePare.count());

50 numere pare de la
1 la 100

22.01.2021 POO 20
Utilizare streams

 Creare streams
 Streams din valori - Stream.of

Stream<String> stream = Stream.of(“streams”, “in”, “java”);


stream.map(String::toUpperCase).forEach(System.out.println);

Stream<String> streamVid = Stream.empty();

22.01.2021 POO 21
Utilizare streams

 Streams din valori nule - ofNullable

String homeVal = System.getProperty(“home”);


Stream<String> homeValStream =
homeVal == null ? Stream.empty() : Stream.of(val);

Stream<String> homeValStream =
Stream.ofNullable(System.getProperty(“home”);

Stream<String> valori =
Stream.of(“config”, “home”, “utilizator”)
.flatMap(key -> Stream.ofNullable(System.getProperty(key);

22.01.2021 POO 22
Utilizare streams

 Streams din arrays - Arrays.stream

int[] numere = {2, 3, 5, 7, 11, 13};


int suma = Arrays.stream(numere).sum();

 Streams din functii – permit crearea stream-urilor infinite


 Stream.iterate, Stream.generate

valoare initiala
Stream.iterate(0, n -> n + 2) lambda de tip
.limit(10) UnaryOperator<T>
.forEach(System.out::println);

22.01.2021 POO 23
Utilizare streams

Java 9 - metoda iterate permite utilizarea unui predicat


predicat care limiteaza
iterarea
IntStream.iterate(0, n -> n < 100, n -> n + 4)
.forEach(System.out::println);
Este utilizarea operatiei filter corecta?
IntStream.iterate(0, n -> n + 4) nu se termina
.filter(n -> n < 100)
.forEach(System.out::println);

22.01.2021 POO 24
Utilizare streams

Utilizarea operatiei takewhile este corecta


IntStream.iterate(0, n -> n + 4)
.takeWhile(n -> n < 100)
.forEach(System.out::println);

 generate – creeaza un stream infinit de valori utilizand lambda de


tip Supplier<T>

Stream.generate(Math::random)
genereaza un stream de 5
.limit(5) numere aleatoare
.forEach(System.out::println);

22.01.2021 POO 25
Utilizare streams

Exemplu – seria Fibonacci – primele 20 de elemente – (0, 1), (1, 1), (1,
2), (2, 3), (3, 5), (5, 8) …

Stream.iterate(new int[]{0, 1}, ????)


.limit(20)
.forEach(t -> System.out::println(“(“ + t[0] + “,” + t[1] + “)”);

Stream.iterate(new int[]{0, 1},


t -> new int[]{t[1], t[0] + t[1]})
.limit(20)
.forEach(t -> System.out::println(“(“ + t[0] + “,” + t[1] + “)”);

22.01.2021 POO 26
Utilizare streams

Seria Fibonacci – 0, 1, 1, 2, 3, 5, 8, …

Stream.iterate(new int[]{0, 1},


t -> new int[]{t[1], t[0] + t[1]})
.limit(20)
.map(t -> t[0])
.forEach(t -> System.out::println);

22.01.2021 POO 27

S-ar putea să vă placă și