I haven't written any code in java8 in the field, so I felt a sense of crisis and learned it, so I will summarize it here.
This is a sample that converts the contents of list into numbers and outputs it. First, an example before java8.
Not java8.java
List<String> suuzies = Arrays.asList("1", "2", null, "3");
for (String suuzi : suuzies) {
if (suuzi == null) {
continue;
}
System.out.println(Integer.parseInt(suuzi));
}
// 1 2 3
Next is java8.
java8.java
List<String> suuzies = Arrays.asList("1", "2", null, "3");
suuzies.stream().filter(s -> Objects.nonNull(s)).map(s -> Integer.parseInt(s))
.forEach(s -> System.out.println(s));
// 1 2 3
Great! It fits in one line and improves readability! When I first saw it, I didn't understand it at all, and I thought what would improve readability. It will be refreshing if you understand it.
The order of stream processing
Considering that you can write the process as if it was connected by an arrow as described above, I certainly feel that the readability has improved. At the field level, if and for often make the nest chaotic, but This seems to be very easy to read.
By the way, the code of java8.java can also be written as follows.
java8(2).java
List<String> suuzies = Arrays.asList("1", "2", null, "3");
suuzies.stream().filter(Objects::nonNull).map(Integer::parseInt)
.forEach(System.out::println);
// 1 2 3
It uses method references, which makes the code even shorter, I will omit the explanation here.
Now that you understand stream, I'll write a little about lambda expressions.
The Stream API provides several methods used for intermediate processing and final processing. For example, the filter method mentioned above looks like this.
Stream.class
Stream<T> filter(Predicate<? super T> predicate);
I had allergies when I first saw it. It closed immediately.
Let's also take a look at (Predicate <? Super T>) in the argument of filter.
Predicate.class
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
default Predicate<T> negate() {
return (t) -> !test(t);
}
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}
This is a functional interface. A lambda expression is one that can implement a functional interface with a short description.
By the way, a functional interface is one in which only one abstract method is defined. Static and default methods other than abstract methods can be included, but they are ignored as a condition. The Predicate class only targets'boolean test (T t)' and ignores others.
As you can see, this interface takes a T-type argument and returns a boolean-type return value. Repeat the filter part of the previous code (java8.java).
java8.java
filter(s -> Objects.nonNull(s))
Implements the filter argument of Stream.class. This part is a lambda expression!
There are several other functional interfaces available. With the map used in java8.class,
Stream.class
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
Let's also look at the contents of the argument Function.
Function.class
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
// and more
}
A method that takes a T type as an argument and returns an R type! In other words, it processes the received arguments and returns them in another form!
Repeat the map part of java8.java earlier.
java8.java
map(s -> Integer.parseInt(s))
You take a character as an argument, convert it to a number, and return it!
The lambda expression syntax looks like this.
(Argument)-> {Processing}
It's a way of writing because there is only one abstract method ♪ There are other Consumers that have no return value and Supplier that take no arguments!
I think the lambda expression was made for Stream! At the beginning of study, I wonder if there is an interface for one abstract method. I thought, but we developers will implement the prepared things in a lambda expression I thought it would be convenient if I used it!
I still have a lot to do, so I will deepen my understanding from now on!
Recommended Posts