Java Stream API Exercise Set
Java Stream API Exercise Set
The Java Stream API allows you to filter and process collections of data in a functional-style programming pattern. To extract only even numbers from a list using Stream API, you can create a stream from the list and apply the `.filter()` intermediate operation, passing a lambda expression that specifies the condition `n -> n % 2 == 0`. This filters the stream to retain only those numbers which are even, i.e., numbers divisible by 2. For example, given `List<Integer> numbers`, you would use: `numbers.stream().filter(n -> n % 2 == 0).forEach(System.out::println);` .
In Java Stream API, the operation to count elements that meet a specific criterion can be accomplished using the `.filter()` method followed by `.count()`. For `List<String> names`, to count those with more than four characters, use: `long count = names.stream().filter(name -> name.length() > 4).count();`. This method counts the number of elements that satisfy the `length > 4` condition. Counting with filters gives insights into data distribution and helps identify patterns or biases in datasets, particularly useful in preliminary data assessment and reporting .
In Java Stream API, `flatMap()` is a powerful intermediate operation that is used to flatten a stream of collections, such as a matrix, into a single stream of elements. This is particularly useful when you have a collection of lists and you want to create a single unified list of elements from all those lists. For example, given a matrix `List<List<Integer>> matrix`, you can use `flatMap()` to flatten it like this: `matrix.stream().flatMap(List::stream).forEach(System.out::println);`. By using `flatMap()`, you eliminate the nested structure of the original lists and can directly process each element as part of a single stream .
The Java Stream API provides the `.anyMatch()` method to evaluate if any elements in a stream satisfy a specified predicate. This method immediately returns `true` upon finding the first match, making it efficient for large datasets. For `List<String> names`, to check if any name starts with "J", use: `boolean hasJ = names.stream().anyMatch(name -> name.startsWith("J"));`. Utilizing such matching simplifies conditional checks across collections, facilitating quick answers to existence questions, which is crucial in decision making processes and data validation steps .
`Collectors.joining()` in Java Stream API is used to concatenate elements of a stream into a single String. Given `List<String> names`, you can concatenate all names with commas as separators using: `String joinedNames = names.stream().collect(Collectors.joining(", "));`. This operation is significant because it transforms a collection of discrete elements into a unified single output that can be easily displayed, logged, or transmitted. It enhances readability and compactness of data when presenting lists or summaries .
The Java Stream API can be used to calculate the average salary of employees by utilizing the `Collectors.averagingDouble()` method. This collector operates on a stream of elements and converts it to a single value representing the average. Given a `List<Employee> employees`, you can get the average salary using: `double averageSalary = employees.stream().collect(Collectors.averagingDouble(Employee::getSalary));`. Calculating averages is important in data analysis as it provides essential insights into the central tendency of the data, aiding in understanding the overall financial structure within an organization .
To determine the employee with the highest salary using Java Stream API, the `.max()` method can be employed along with a comparator that compares employees based on salary. Given `List<Employee> employees`, you would use: `employees.stream().max(Comparator.comparingDouble(Employee::getSalary)).orElse(null);`. This operation traverses the list and applies the comparator to find the maximum element based on the defined criteria, which in this case is the salary. This operation is significant as it simplifies the process of identifying extremes in a dataset without explicit iteration logic, leveraging the streamlined syntax and functionality of streams .
The transformation of each element in a collection, such as converting all strings to uppercase, can be accomplished using the `.map()` intermediate operation. In Java Stream API, `map()` applies a given function to each element of the stream, creating a new stream with the transformed elements. Given `List<String> names`, to convert each string to uppercase, you would use `names.stream().map(String::toUpperCase).forEach(System.out::println);`. This transformation is crucial for data processing as it ensures consistency in data representation, often a requirement for further operations such as sorting or comparison .
In Java Stream API, `Collectors.partitioningBy()` is used to separate elements in a stream into two groups based on a predicate. This results in a Map with Boolean keys: `true` for elements that satisfy the predicate and `false` for elements that do not. To partition `List<Integer> numbers` into even and odd, use: `numbers.stream().collect(Collectors.partitioningBy(n -> n % 2 == 0));`. This separates numbers into two groups, even (key `true`) and odd (key `false`). This distinction is useful for cases where logic varies based on data characteristics, simplifying processing of different categories separately without multiple filter operations .
In Java Stream API, `Collectors.groupingBy()` is used to group elements of a list by a specified classifier function, such as grouping strings by their first letter. This approach turns the stream into a Map, where the keys are the values returned by the classifier function, and the values are Lists of items that share that key. For instance, given `List<String> names`, to group by the first letter you can use `names.stream().collect(Collectors.groupingBy(name -> name.substring(0, 1)));`. This will create a Map where each entry corresponds to a letter with the list of names starting with that letter .