HTML prezentacija / Java Stream API
Koristi ← → ili dugmad za navigaciju
Kratka prezentacija

Lambda funkcije u Javi i rad sa kolekcijama

01 / 07

Kratak pregled lambda izraza u Javi i praktična upotreba metoda map, filter i reduce nad kolekcijama.

  • Šta su lambda funkcije i zašto su korisne
  • Kako se koriste uz Stream API
  • Primeri koda spremni za prezentaciju ili vežbu
Osnovni pojam

Šta su lambda funkcije?

02 / 07
  • Lambda funkcije su anonimne funkcije koje omogućavaju funkcionalni stil programiranja u Javi.
  • Najčešće se koriste za implementaciju funkcionalnih interfejsa na kraći i čitljiviji način.
  • Posebno su korisne uz Stream API i rad sa kolekcijama.

Sintaksa: (parametri) -> izraz

Primer lambda izraza
import java.util.function.BinaryOperator;

BinaryOperator<Integer> saberi = (a, b) -> a + b;

System.out.println(saberi.apply(5, 3));
// Ispisuje 8
Stream API

map — transformacija elemenata

03 / 07

Metoda map transformiše svaki element kolekcije u novi oblik. Koristi se kada želimo da promenimo vrednosti, a ne da ih filtriramo.

Primer sa stringovima
List<String> imena = Arrays.asList("Ana", "Marko", "Jelena");

List<String> velikaImena = imena.stream()
    .map(name -> name.toUpperCase())
    .collect(Collectors.toList());

System.out.println(velikaImena);
// [ANA, MARKO, JELENA]
Stream API

filter — filtriranje elemenata

04 / 07

Metoda filter zadržava samo elemente koji ispunjavaju zadati uslov. Lambda izraz vraća true ili false.

Primer sa brojevima
List<Integer> brojevi = Arrays.asList(1, 2, 3, 4, 5, 6);

List<Integer> parniBrojevi = brojevi.stream()
    .filter(n -> n % 2 == 0)
    .collect(Collectors.toList());

System.out.println(parniBrojevi);
// [2, 4, 6]
Stream API

reduce — agregacija elemenata

05 / 07

Metoda reduce kombinuje sve elemente kolekcije u jedan rezultat, na primer sumu, proizvod ili maksimalnu vrednost.

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

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

System.out.println(suma);
// 15
Alternativni pristup

Da li isto može samo uz forEach?

06 / 07

Da — slična funkcionalnost može da se postigne i pomoću forEach, ali uz više ručnog koda i manje elegancije nego sa Stream API pristupom.

map uz forEach
List<String> imena =
    Arrays.asList("Ana", "Marko", "Jelena");
List<String> velikaImena =
    new ArrayList<>();

imena.forEach(name -> {
    velikaImena.add(name.toUpperCase());
});

System.out.println(velikaImena);
// [ANA, MARKO, JELENA]
filter uz forEach
List<Integer> brojevi =
    Arrays.asList(1, 2, 3, 4, 5, 6);
List<Integer> parniBrojevi =
    new ArrayList<>();

brojevi.forEach(n -> {
    if (n % 2 == 0) {
        parniBrojevi.add(n);
    }
});

System.out.println(parniBrojevi);
// [2, 4, 6]
reduce uz forEach
List<Integer> brojevi =
    Arrays.asList(1, 2, 3, 4, 5);
int[] suma = {0};

brojevi.forEach(n -> suma[0] += n);

System.out.println(suma[0]);
// 15

Zaključak

  • forEach može da imitira map, filter i reduce.
  • Potrebno je ručno praviti novu listu ili promenljivu za rezultat.
  • Stream API je obično čitljiviji i bliži funkcionalnom stilu.

Posebno kod reduce, vidi se da forEach traži pomoćnu promenljivu, pa je rešenje manje elegantno.

Zaključak

Kratak rezime

07 / 07
Metoda Opis Primer upotrebe
map Transformiše elemente Pretvaranje stringova u velika slova
filter Filtrira elemente po uslovu Izbor parnih brojeva
reduce Kombinuje elemente u jedan rezultat Sabiranje svih brojeva u listi

Lambda izrazi čine kod kraćim, čitljivijim i veoma praktičnim za obradu kolekcija uz Java Stream API.

Pojašnjenje dodatnih pojmova

BinaryOperator<T> je funkcionalni interfejs koji predstavlja operaciju nad dva argumenta istog tipa i vraća rezultat istog tipa. Koristi se za lambda izraze koji kombinuju dva elementa u jedan.

BinaryOperator<Integer> saberi = (a, b) -> a + b;
int rezultat = saberi.apply(5, 3); // rezultat je 8

collect(Collectors.toList()) prikuplja elemente stream-a u novu List kolekciju. Bez poziva ove metode dobijate stream, koji nije kolekcija i ne može se koristiti kao lista (npr. ne možete pozvati get(index)).

List<String> velikaImena = imena.stream()
    .map(name -> name.toUpperCase());
// velikaImena je STREAM, ne LISTA — neće raditi kao lista

List<String> velikaImenaLista = imena.stream()
    .map(name -> name.toUpperCase())
    .collect(Collectors.toList());
// velikaImenaLista je prava lista, može se koristiti kao i svaka druga lista