Streams Flashcards
Kunnen we een stream pipeline maken zonder intermediate operator?
En kan dit ook zonder terminal operator?
Ja
Ja. Maar houd in het achterhoofd dat streams ‘lazy’ zijn en er dus niets mee gebeurt zonder terminal operator.
Wat zijn de zes intermediate operators voor een stream?
map(), filter(), distinct(), sorted(), limit(), skip()
Noem 5 voorbeelden van terminal operators voor streams
forEach(), toArray(), reduce(), collect(), min(), max(), count(), anyMatch(), allMatch(), noneMatch(), findFirst(), findAny()
Wat zijn de verschillen tussen intermediate en terminal operators in streams?
Intermediate operators zullen altijd iets returnen, omdat dit meegenomen moet worden naar een volgende operator. Terminal operators returnen niet altijd iets.
We kunnen meerder intermediate operators chainen in een pipeline. Maar er mag slechts 1 terminal operator zijn.
Kunnen we met een stream de bron (bijv. een arraylist) aanpassen?
Nee. We kunnen enkel een nieuwe arraylist aanmaken waarin we nieuwe waardes zetten.
Beschouw deze code:... myVariable = myProducts
.stream()
.filter(product -> product.price > 3);
Wat is het type van myVariable?
Stream
of Stream<Integer>
.
Omdat het geen terminal operator bevat is dit een Stream.
Kunnen we een stream maken en hier meteen waardes in zetten om over te itereren?
Zo ja, hoe?
Jazeker, met Stream.of
bijvoorbeeld:
Stream<String> myStream = Stream.of("Hello", "my", "world");
Wat is het verschil tussen de map en flatmap operator voor streams?
Een map neemt een object als input, doet daar iets mee en returnt iets als output. De output maakt niet uit, maar dient wel overeen te komen met een eventueel toegewezen type.
Een flatMap neemt een object als input en returnt een stream. Dit kan zinvol zijn wanneer je meerdere Lists terug wil brengen tot 1 list.
Meer info
Wat is het verschil tussen findFirst en findAny?
findFirst is in de meeste gevallen zinvol en voldoende. Het vindt het eerste element in de collectie.
In parallel processing kan findAny zinvoller zijn, omdat deze operator geen rekening houdt met volgorde.
Hoe check ik of een stream minstens 1 item bevat met een bepaalde waarde.
met anyMatch
deze method vraagt een predicate lambda en returnt dus een boolean als de geformuleerde conditie(s) klopt / kloppen.
anyMatch is een terminal operator en returnt een boolean.
Hoe check ik of alle items in een stream een bepaalde waarde bevatten.
met allMatch
deze method vraagt een predicate lambda en returnt dus een boolean als de geformuleerde conditie(s) klopt / kloppen.
allMatch is een terminal operator en returnt een boolean.
Hoe converteer ik een stream naar een List, Map of Set?
met de collect method:.collect(Collectors.toList)
als terminal operator te gebruiken. toList kan ook toMap
of toSet
zijn.
Hoe genereer ik een stream met waarden?
met Stream.generate()
we kunnen bijvoorbeeld zeggen:Stream.generate(UUID::randomUUID);
let er wel op dat deze stream nu infinite is, en dus een limiet nodig heeft.
met .limit(10)
als intermediate operator zorgen we ervoor dat er 10 uuids worden gegenereerd.
Stel, ik heb een ArrayList:List<Integer> myList = Arrays.asList(12, 3, 7, 24, 44, 19);
Wat moet ik doen om deze waarden met een stream bij elkaar op te tellen?
Bijvoorbeeld:int total = myList.stream().reduce((item, subTotal) -> { return item + subTotal; }).get();
dit kan nog afgekort worden tot:int total = myList.stream().reduce(Integer::sum).get();
beschrijf .reduce in streams:
- is het een terminal of intermediate operator?
- wat neemt het op en wat geeft het terug?
reduce is een terminal operator.
Deze operator is bedoeld om verschillende lists, sets of andere collecties plat te slaan tot 1 waarde (als een string of een int)
het vereist een initiële waarde (vaak 0 of een lege string), en twee parameters. 1 voor het subtotaal en 1 voor hetgeen dat daarbij opgeteld / afgetrokken wordt.
Voorbeeld:
String names = persons.stream()
.map(Person::getName)
.reduce(“”, (acc, name) -> acc + name);