Nowadays Java lambda expressions and Stream API

It's been a long time since the release of Java8, but I've been using lambda expressions and Stream API somehow so far, so I'll summarize it again.

Lambda expression

Lambda expressions are an easy way to implement an interface that has only one method, called a functional interface.

Functional interface

In functional languages like lisp and languages with function pointers like C, you can easily pass a "function", but in java you can't pass it unless the function is an object. Therefore, by preparing a functional interface as shown below, it is possible to pass a function.

Func.java


package jp.foo;

public interface Func {
	public double apply(double x);
}

A functional interface is an interface that has only one abstract method.

Implementation of functional interface

Until java7, the abstract method was overridden as follows.

Func g = new Func(){
	@Override
	public double apply(double x) {
		return x * x;
	}
};

In java8, the description can be simplified as follows by taking advantage of the fact that the functional interface has only one method. This is a lambda expression.

Func f = x -> x * x;

If you write a little more tightly

Func f = (x) -> {return x * x;};

Generally, it is described as (argument 1, argument 2, ...)-> {process 1; process 2; ...}. Of course, if there is no argument or no return, you can write it empty like ()-> {}. This is just overriding a single method in the functional interface. The functional interface simplifies the description by taking advantage of the fact that there is only one method to override.

This lambda expression is useful, for example, when using a method that takes a functional interface as an argument (for example, as shown below).

FuncUser.java


package jp.foo;

public class FuncUser {
	public static void samplePrintFunc(Func f) {
		for(double x = 1.0; x <= 3.0; x += 1.0) {
			System.out.println(f.apply(x));
		}
	}
}

The simple description will be as follows.

FuncUser.samplePrintFunc(x -> x * x);
FuncUser.samplePrintFunc(x -> Math.sin(x));

If the process becomes a little complicated, you can describe multiple processes by enclosing them in {// describe multiple processes}.

FuncUser.samplePrintFunc(x -> { a = Math.sin(x); b = Math.cos(x); return a * b; });

If there is only one process and the argument type of the functional interface and the argument type of the method you want to use are the same, you can omit it as follows.

FuncUser.samplePrintFunc(Math::sin);

Lambda expressions are thus a powerful grammar for passing functions.

Stream API

The Stream API is a tool that performs collection processing using lambda expressions as described above. It's an API designed with a lambda expression. I've summarized the ones I use often as an example.

forEach It seems that only forEach can be used without calling the stream method.

Arrays.asList(new Double[] { 1.0, 2.1, 3.2, 4.3, 5.4 }).forEach(System.out::println);

filter It is convenient because it performs a refined search. It's easy because you don't have to write an if statement in each for statement.

Arrays.asList(new Double[] { 1.0, 2.1, 3.2, 4.3, 5.4 }).stream().filter(x -> x > 3.0).forEach(System.out::println);

map It is used when you want to create another list and set from list or set.

Arrays.asList(new Double[] { 1.0, 2.1, 3.2, 4.3, 5.4 }).stream().map(x -> x * x).forEach(System.out::println);

collect collect is powerful and almost eliminates writing for statements.

Write collect (supplier (variable placed outside for), accumulator [process inside for], combiner [process to collect supplier at the time of parallel processing]).

Arrays.asList(new Double[] { 1.0, 2.1, 3.2, 4.3, 5.4 }).stream().collect(HashMap::new, (map, x) -> map.put(x, x * x), (map1, map2) -> map1.forEach(map2::put)).entrySet().forEach(System.out::println);

Also, it is convenient to use Collectors. The processing that you often do is well abstracted and complete.

Arrays.asList(new Double[] { 1.0, 2.1, 3.2, 1.0, 5.4 }).stream().collect(Collectors.toSet()).forEach(System.out::println);

mapToDouble etc... If you use the mapTo [numerical value] stream, you can use average, max, and min, which is useful.

Arrays.asList(new Double[] { 1.0, 2.1, 3.2, 4.3, 5.4 }).stream().mapToDouble(x -> x).average().ifPresent(System.out::println)

Try to find the standard deviation

Let's find the standard deviation.

\sigma = \sqrt{\frac{1}{n} \sum_{i = 1}^n (x_i - \mu)^2}

The following desired part itself is multiplied by 2 lines (2nd and 3rd lines).

List<Double> sample = Arrays.asList(new Double[] { 1.0, 2.1, 3.2, 4.3, 5.4 });
double mu = sample.stream().mapToDouble(x -> x).average().getAsDouble();
double siguma = Math.sqrt(sample.stream().map(x -> Math.pow(x - mu, 2.0)).mapToDouble(x -> x).average().getAsDouble());
System.out.println(siguma);

Recommended Posts

Nowadays Java lambda expressions and Stream API
Handle exceptions coolly with Java 8 lambda expressions and Stream API
[For beginners] About lambda expressions and Stream API
Use Java lambda expressions outside of the Stream API
Java Stream API
[Java] Stream API / map
Understand Java 8 lambda expressions
Java8 Stream API practice
About Java lambda expressions
Explain Java 8 lambda expressions
[Java] Sort the list using streams and lambda expressions
Java Stream API in 5 minutes
Java8 stream, lambda expression summary
[Java] Introduction to lambda expressions
[Java] Stream API --Stream termination processing
[Java] Stream API --Stream intermediate processing
[Java] Introduction to Stream API
[Java] Stream API intermediate operation
Rethinking design patterns with Java8 lambda expressions & Stream --Builder pattern -
About C # lambda expressions and Linq
Java lambda expressions learned with Comparator
[Introduction to Java] About lambda expressions
Java for beginners, expressions and operators 1
About Lambda, Stream, LocalDate of Java8
Java for beginners, expressions and operators 2
I tried using Java8 Stream API
Getting started with Java lambda expressions
Java 8 ~ Stream API ~ to start now
The origin of Java lambda expressions
How to use Java lambda expressions
Implement API Gateway Lambda Authorizer in Java Lambda
Data processing using stream API from Java 8
Try using the Stream API in Java
[Java] for Each and sorted in Lambda
Try various Java Stream API methods (now)
Notes on Java's Stream API and SQL
Java8 / 9 Beginners: Stream API addiction points and how to deal with them
Interact with LINE Message API using Lambda (Java)
Stream API memo
Create API using Retrofit2, Okhttp3 and Gson (Java)
[JAVA] Stream type
[Java] Summary of how to abbreviate lambda expressions
Try Java 8 Stream
Effective Java 3rd Edition Chapter 7 Lambda and Streams
How to use Java API with lambda expression
Java and JavaScript
I've reviewed Java's lambda expression, stream API, six months after I started Java.
XXE and Java
Java8 to start now ~ forEach and lambda expression ~
Hello Java Lambda
[Java] Lambda expression
Studying Java 8 (Stream)
Java Stream termination
[Java] How to operate List using Stream API
Java lambda expression
[Java] Stream processing
Stream API basics
Java 9 Optional :: stream
Java8 Lambda expression & Stream design pattern reconsideration --Command pattern -
Organize your own differences in writing comfort between Java lambda expressions and Kotlin lambda expressions.
I tried Mastodon's Toot and Streaming API in Java