Java 8 Stream Practice Exercises
Java 8 Stream Practice Exercises
To convert a list of strings into a Map in Java 8 where each string is associated with its length, use `Collectors.toMap` in conjunction with the `stream` API. For example: `strList.stream().collect(Collectors.toMap(x -> x, x -> x.length()))` creates a Map where keys are the strings and values are their respective lengths .
To sort an array of integers and convert it into a Stream, employ `Arrays.sort(arr)` to first sort the array, followed by `Arrays.stream(arr).forEach(System.out::println)` to convert the sorted array into a Stream for processing or output .
The `Consumer` interface accepts a single argument and performs an operation without returning any result, making it useful for operations like printing (`Consumer<String> consumer = str -> System.out.println(str)`). The `Predicate` interface takes an argument and returns a boolean, primarily used for filtering (`Predicate<Integer> evenPredicate = n -> n % 2 == 0`). The `Supplier` interface provides results without any input, useful for lazy initialization or deferred execution (`Supplier<String[]> supplier = () -> new String[] {"One", "Two", "Three"}`).
The `map` method is used to transform each element in a stream, which might change the element type, enabling one-to-one mapping such as converting strings to their uppercase forms. After transformation using `map`, `collect` is typically used to gather the results into a desired collection format, such as a list, set, or map (`Collectors.toList()`, `Collectors.toSet()`). For example, converting a string list to uppercase involves `strList.stream().map(x -> x.toUpperCase()).collect(Collectors.toList())` .
`Function` in Java 8 is used to apply transformations and return a result, usually seen in mapping operations, like transforming characters in a string list using `Function<String, Character> function = str -> str.charAt(0)`. `Predicate`, on the other hand, evaluates a condition and returns a boolean, and is typically used in filtering: `Predicate<String> predicate = str -> str.contains("p")`. Use `Function` for transformations where a result is expected and `Predicate` for conditional checks .
A list of integers can be processed using Java Streams to identify numbers starting with a particular digit by converting each number to a string and applying a filter. For instance, to find numbers starting with '1', use: `list.stream().filter(x -> String.valueOf(x).startsWith("1")).collect(Collectors.toList())`, which filters and collects numbers starting with the specified digit .
`flatMap` transformations involve each element being transformed into a stream, resulting in flattening of the elements into a single stream. This is ideal for merging multiple collections or dealing with nested collections, such as flattening lists of lists into a flat list (`evenOdd.stream().flatMap(x -> x.stream()).collect(Collectors.toList())`). Conversely, `map` maintains the structure of one input to one output and does not alter the nesting level, as seen in mapping strings to their lengths .
`map()` transforms each element of a stream into another object and results in a stream of the same size, hence used for one-to-one transformation. For example, converting a list of integers to their factorials. In contrast, `flatMap()` is used for one-to-many transformations, transforming each element into multiple resulting in flattening nested structures, such as combining lists into a single list. For instance, two lists of integers can be flattened using `evenOdd.stream().flatMap(x -> x.stream()).collect(Collectors.toList())` .
To sort a list of Employee objects by salary using Stream functions in Java 8, you can employ the `sorted` method with a comparator that compares employees based on their salary. For example: `empList.stream().sorted((e1, e2) -> e1.salary - e2.salary).collect(Collectors.toList())` sorts the `empList` in ascending order by salary .
To identify duplicate elements using Java Stream functions, you can utilize list indexing compared with last indices within a filter, i.e., `list.stream().filter(x -> list.indexOf(x) != list.lastIndexOf(x)).collect(Collectors.toList())`, which provides duplicates as a list. Alternatively, leveraging a `HashSet`, duplicates can be found using a condition `tempSet.add(x) == false` within a filter, which generally improves efficiency as it avoids multiple list traversals .