Lambdas, the Stream API and Optional in tests
A lambda is a short way to write an implementation of a functional interface (an interface with a single abstract method). The most common ones:
Predicate<T>— takes a value, returnsboolean(filter);Function<T,R>— transforms a value (map);Consumer<T>— takes a value, returns nothing (forEach);Supplier<T>— takes nothing, returns a value (orElseGet);Runnable,Callable<V>— an action without arguments.
A method reference shortens a lambda: WebElement::getText instead of e -> e.getText(). A lambda sees only effectively final local variables, so a counter cannot be changed inside it (use AtomicInteger or count()).
Selenium waits are lambdas too: wait.until(d -> d.findElement(By.id("ready")).isDisplayed()), because ExpectedCondition<T> extends Function<WebDriver, T>.
List<String> titles = rows.stream()
.filter(WebElement::isDisplayed)
.map(WebElement::getText)
.filter(t -> !t.isBlank())
.toList(); // Java 16+, an unmodifiable list
A Stream is a pipeline: a source → intermediate operations (filter, map, sorted, distinct), which are lazy and do nothing by themselves, → a terminal operation (toList, collect, count, anyMatch, findFirst, forEach) that triggers the computation. A stream can be used only once. Typical tasks: check that a list is sorted, that all elements satisfy a condition (allMatch), group (Collectors.groupingBy). Avoid parallelStream() in tests with a shared driver or state.
Optional is a "value may be absent" container for a method result (findFirst). Extract with orElseThrow() and a clear message, orElse, orElseGet, ifPresent. get() without a check throws NoSuchElementException. Do not use Optional as a field or parameter.