Lambda expressions

Let’s start with the basic LAMda expression

Java8 has new language-level features that are different from functional programming languages such as javascript. A lambda expression is still an object in Java. It must be attached to a special object type, Functional Interface. (Called method references or functional interfaces)

grammar

(arg1, arg2...) -> { body }(type1 arg1, type2 arg2...) -> { body }Copy the code
  1. Simply put, you can think of a method without access modifiers, return value declarations, and names

  2. Parameter types can be omitted for automatic inference

  3. If there is only one argument, () can be omitted

  4. The return type of the anonymous function is the same as the return type of the code block, or null if there is no return

  5. Function body. {} can be omitted if there is only one statement

  6. Each Lambda expression can be implicitly assigned to a functional interface

    For example, Runnable is a FunctionalInterface (annotated with @functionalinterface)

    Runnable r = () -> System.out.println(“hello world”);

  7. When no functional interface is specified, the compiler automatically interprets this conversion

    new Thread(

    () -> System.out.println(“hello world”)

    ).start();

The double colon (::) operator

Another way to turn a regular method into a Lambda expression

Differences from anonymous classes

One big difference is the use of keywords.

For anonymous classes, the keyword this is read as an anonymous class, and for Lambda expressions, the keyword this is read as an external class that uses Lambda.

Another difference lies in the compilation method.

The Java compiler compiles Lambda expressions and converts them to private functions inside the class, which it dynamically binds using the invokeDynamic directive, a new addition to Java 7


Method reference or function interface

The annotation FunctionalInterface mentioned above can be translated as a method reference or function interface.

Added in Java8 to specify that the interface type declaration is a functional interface defined according to the Java language specification. A functional interface can have only one abstract method

/ / define a functional interface @ FunctionalInterfacepublic interface WorkerInterface {public voiddoSomeWork(); }public class WorkerInterfaceTest {public static void execute(WorkerInterface worker) { worker.doSomeWork(); }public static void main(String [] args) {// Execute (new)WorkerInterface() {      @Override      public void doSomeWork() {          System.out.println("Worker invoked using Anonymous class"); }}); // Use lambda expression execute(() -> system.out.println ()"Worker invoked using Lambda expression") );}}Copy the code


Commonly used API

The Collection of the interface

The Collection interface provides the stream() method

Anything we do will not affect the source collection, and you can extract multiple streams on a collection at the same time.

A static method

of

Construct a Stream object

Stream<String> s1 = Stream.of("a"."b");Copy the code
empty

Create an empty Stream object.

contact

Connect two Streams, return a new Stream without changing either Steam object.

Stream<String> s1 = Stream.of("a"."b"); Stream<String> s2 = Stream.of("c"."d"); Stream<String> s3 = Stream.concat(s1, s2);Copy the code
generate

Create an infinite Stream, usually for random number generation

Stream<Double> s5 = Stream.generate(Math::random);Copy the code
iterate

Create an infinite Stream. You can add initial elements and production rules

Stream<Integer> s4 = Stream.iterate(1, n -> n + 2);Copy the code


Instance methods

Returns the Stream
peek

Processing each of these elements returns a new Stream

Used for debugging to print the current element

map

This is typically used for each element. Like from one type to another type

List<String> stringList = integerStream.map(n -> "I am" + n).collect(Collectors.toList());Copy the code
Differences between Peek and Map

Peek is used only for debugging and printing information

The Consumer interface of the peek argument, which has no return value

@FunctionalInterfacepublic interface Consumer<T> {  void accept(T t);Copy the code

The map argument is the Function interface and must be returned

@FunctionalInterfacepublic interface Function<T, R> {  R apply(T t);Copy the code
One more question
integerStream. Peek or map(item -> system.out.println ("= = = = = = = = ="));Copy the code

The printing of this sentence will not be executed without the termination of “collect”.

That is, the flow method actually executes when it terminates method firing

mapToInt

Convert an element to an int, usually followed by sum, Max, min, and average

mapToLong

slightly

mapToDouble

slightly

limit

Limit the number of

distinct

Deduplicate functions. This is determined by the elements’ equals and hashCode methods. (Both need to be rewritten)

The basic elements

Stream<Integer> integerStream = Stream.of(2, 5, 100, 5); List<Integer> collect =integerStream.distinct().collect(Collectors.toList()); System.out.println(JSONUtil.toJsonStr(collect));Copy the code

,5,100 [2]

object

@Getter@Setterclass User { private String name; private int age; }@Testpublic voiddistinct() {  User a = new User();  a.setName("yun");  a.setAge(20);  User b = new User();  b.setName("yun"); b.setAge(20); Stream<User> userStream = Stream.of(a, b); List<User> userList = userStream.distinct().collect(Collectors.toList()); System.out.println(JSONUtil.parse(userList)); }Copy the code

When you just write the getter/setter method

[{“name”:”yun”,”age”:20},{“name”:”yun”,”age”:20}]

Add @ EqualsAndHashCode

[{“name”:”yun”,”age”:20}]


sorted

Sort, base elements can use the default sort method

Stream<String> strStream = Stream.of("ba"."bb"."aa"."ab"); strStream.sorted().forEach(item -> System.out.println(item));Copy the code

aa ab ba bb

You can also customize the sorting method

Custom sort by second letter

      Stream<String> strStream = Stream.of("ba"."bb"."aa"."ab");      Comparator<String> comparator = (x, y) -> x.substring(1).compareTo(y.substring(1));      strStream.sorted(comparator).forEach(item -> System.out.println(item));Copy the code

ba aa bb ab

filter

filter

Stream<Integer> integerStream = Stream.of(2, 5, 100, 5);integerStream.filter(item -> item > 10).forEach(item -> System.out.println(item));Copy the code

100


Method to terminate a type
max

Gets the maximum value in the Stream

Stream<Integer> integerStream = Stream.of(2, 5, 100, 5); Integer max =integerStream.max(Integer::compareTo).get();Copy the code
min

Get the minimum

findFirst

Gets the first element

Integer i = integerStream.findFirst().get();Copy the code
findAny

Get an element at random. In the serial case, it’s the first one. Parallelism doesn’t have to be the first to get it.

count

Returns the number of elements in the stream

long count = integerStream.count();Copy the code


collection

The resulting Stream, summed up as collection Collectors, already provides a number of ready-to-use Collectors. Collectors. ToList (), Collectors. ToSet (), and Collectors. ToMap () are often used.

Other advanced uses include Collectors. GroupingBy () for grouping

// userId:List<User>Map<String,List<User>> Map = user.stream().collect(Collectors. GroupingBy (User::getUserId)); // Return userId: number of groups Map<String,Long> Map = user.stream().collect(Collectors.groupingBy(User::getUserId,Collectors.counting()));Copy the code
toArray

Collection returns a list, map, etc. ToArray returns an array

      Stream<Integer> integerStream = Stream.of(2, 5, 100, 5);      // Object[] objects = integerStream.toArray();      Integer[] toArray = integerStream.toArray(Integer[]::new);Copy the code

If no parameter, an Object array is returned. Integer[]::new can be added, and an Integer array can be returned

forEach

I’m going to do it for each element

Unlike a map, forEach does not return a Stream and consumes it

forEachOrdered

The function is the same as forEach, except that forEachOrdered consumes the elements in the Stream in the order in which they were inserted.

When using parallelism, there is a difference.

reduce

You can learn the Map/Reduce calculation model.

Stream<Integer> integerStream = Stream. Of (1, 2, 3); Integer sum =integerStream.reduce(100, (x, y) -> x + y);      System.out.println(sum);Copy the code

Provide an initial value of 100 and start adding up

106

Although reduce is rarely used, many Collectors methods, such as groupingBy, minBy, and maxBy, are used.


The parallel method

Creating a parallel Stream

The Stream of (1, 2, 3). The parallel (); List<Integer> SRC = arrays. asList(1, 2, 3); Stream<Integer>integerStream = src.parallelStream();Copy the code

Parallel streams and regular streams support basically the same API

By default, a ForkJoinPool thread pool is used for parallel streams. Customization is also supported, though this is not usually necessary. ForkJoin’s divide-and-conquer strategy fits nicely with parallel stream processing.

While parallelism sounds like a nice word, using parallel streams is not always the right thing to do, and many times it’s not necessary at all.

Such as

      Stream<Integer> integerStream = Stream of (1, 2, 3). The parallel (); Integer sum =integerStream.reduce(100, (x, y) -> x + y);      System.out.println(sum);Copy the code

So this becomes 306






END
Thank you for reading