1. Checking
I think you might already be bored with learning how to chain together data streams. You want to finally do something with the data.
The Stream
class has three standard methods that do not construct streams, but instead check what kind of data is in them. These methods are: anyMatch()
, allMatch()
, and noneMatch()
.
boolean anyMatch(rule)
method
This method checks whether the stream has at least one element that satisfies the rule that is passed to the method. If there is such an element, the method returns true
, otherwise false
.
Examples
Code | Note |
---|---|
|
|
|
|
|
|
In the last example, we first retain only the elements that are less than zero, and then we check the result to see whether any of filtered elements is greater than zero. Of course, such elements are no longer there.
boolean allMatch(rule) method
This method checks whether all elements in the stream match the rule (also known as a predicate). The rule is passed as an argument to the method:
Code | Note |
---|---|
|
(all elements greater than zero)
|
|
(are there elements less than or equal to zero?)
|
|
(we retained the elements that are less than zero)
|
In the last example, we first allow only elements that are less than zero to pass through the filter, and then we check whether all the retained elements are less than zero. The check yields a positive result.
boolean noneMatch(rule) method
The noneMatch()
method checks whether the stream has no elements that match the passed rule. It is like the opposite of the anyMatch()
method.
Code | Note |
---|---|
|
|
|
|
|
|
2. Utility classes: Optional
class
Sometimes it is very inconvenient for programmers to work with null
references. For example, suppose you are comparing two strings. If both variables are not null
, then you can simply call s1.equals(s2)
, and everything will work. But if s1
could be null
, then you have to write code that handles this situation in order to avoid a NullPointerException
.
That's why programmers came up with the Optional<T>
utility class. Its code looks roughly like this:
Code | Note |
---|---|
|
Checks whether the value is not null
Checks whether the value is null
Returns the stored value. Throws an exception if the value is null. Returns the stored non-null value. Or if the stored value is null , then returns the value passed in as a method argument
Returns the stored non-null value or throws an exception if the value is null. |
The purpose of this class is simply to store a T object (a reference to an object whose type is T). The object reference inside an Optional<T>
object can be null
.
This class lets programmers write slightly prettier code. Let's compare:
Using Optional | Not using Optional |
---|---|
|
|
One Optional
object can always be compared to another Optional
object using the equals
method, even if they store null
references.
Simply speaking, the Optional
class lets you write "beautiful" checks for null
and "beautiful" actions in the event that an Optional
object stores a null
value.
3. Finding elements
Let's return to the Stream
class. The Stream
class has 4 more methods that let you search for elements in a stream. These methods are findFirst()
, findAny()
, min()
, and max()
.
Optional<T> findFirst()
method
The findFirst()
method simply returns the first element in the stream. That's all it does.
The more interesting thing to note here is that the method does not return a T
object, but rather an Optional<T>
wrapper object. This ensures that the method will never return null
after failing to find an object.
Example:
ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
String str = list.stream().findFirst().get(); // Hello
For greater clarify, let's break the last line into several lines:
ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
Stream<String> stream = list.stream();
Optional<String> result = stream.findFirst();
String str = result.get(); // Hello
The last get()
method is simply retrieves the value stored inside the Optional
object.
Optional<T> findAny()
method
The findAny()
method returns any element from the stream and ends there. This method is similar to findFirst()
, but it is great for streams used in parallel operations.
When processing streams in parallel, it may be an element has already been found in some part of a stream, but it is not yet clear whether it is the first or not.
If many elements have matched all the filters, and it is important for the programmer to get exactly the first of them, then the findFirst()
method is what should be called. If the programmer knows that in reality 0 or 1 element will match all the filters, then it is enough to simply call findAny()
— and this will be faster.
Optional<T> min(Comparator<T>)
method
The min()
method uses a comparator
object to compare all elements in the stream and returns the minimum element. The most convenient way to define a comparator object is with a lambda function.
Example of searching for the shortest string:
ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
String min = list.stream().min( (s1, s2)-> s1.length()-s2.length() ).get();
Optional<T> max(Comparator<T>)
method
The max()
method uses a comparator
object to compare all elements in the stream and returns the maximum element. The most convenient way to define a comparator object is with a lambda function.
Example of searching for the longest string:
ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
String max = list.stream().max( (s1, s2)-> s1.length()-s2.length() ).get();
GO TO FULL VERSION