Lambda expressions

Lambda is an instance object of an anonymous implementation class of a FunctionalInterface that uses the @functionalinterface annotation to limit the interface to only one method to be implemented

format

  • -> The arrow operator
  • To the left of -> is the input parameter. The type of the input parameter can be omitted. Multiple input parameters need to be added(a)
  • -> To the right is the Lambda body, which is the method body of the implementation class. If only one line can be omitted{}

Abbreviated format

No parameter + no return value
() -> System.out.println("xxx");
Copy the code

If the method body has only one line, you can omit {}

Parameter + no return value
(String s1) -> System.out.println(s1);
(String s1, String s2) -> System.out.println(s1 + s2);
Copy the code
The input parameter type is omitted

Omit the input parameter type, and the compiler does type inference

(s1) -> System.out.println(s1);
(s1, s2) -> System.out.println(s1 + s2);
Copy the code
There is only one input
s1 -> System.out.println(s1);
Copy the code
Returns a value

The method body is a single line, and return can be omitted

i1 -> String.valueOf(i1);
Copy the code

Direct method references, incoming parameters, and returns can be omitted

String::valueOf
Copy the code

The body of a method has multiple lines, and neither {} nor return can be omitted

i1 -> {
  System.out.println(i1);
  return String.valueOf(i1);
}
Copy the code

Stream flow operation

This is a high-level iterator that operates on collections for common operations such as finding and filtering

The process of Stream operation is divided into: create Stream object -> intermediate operation -> terminate operation

Knowledge:

  1. When the abort operation has been performed, the flow can no longer perform intermediate operations
  2. The intermediate operation is not executed until the terminating operation is performed, which is called inertia
  3. Intermediate operations are classified into stateless operations and stateful operations
  4. In a stateless operation, each element is executed in the order of the operation, and not all elements complete one step before moving on to the next step together
  5. Stateful operations wait until all of the previous intermediate operations have been performed, such as elements grouped in separate threads for stateless operations, and sorting operations wait until all of the other threads have completed before they can be performed
  6. Serial stream callparallel()Can become a parallel stream
  7. Parallel flow callsequential()Can become serial stream
  8. Multiple successive callsparallel()andsequential()The reason is that calling these two methods will only change the current streamsourceStage.parallelThis attribute

Create a flow

Series flow
int[] nums = {1.2.3.4.5};
// The following two arrays are of any type
Arrays.stream(nums);
Stream.of(nums);
// The Stream class. Of () method for the basic type
IntStream.of(nums);
// Create int stream 1-9
IntStream.range(1.10).forEach(System.out::println);
// Create an int stream from 1 to 10
IntStream.rangeClosed(1.10).forEach(System.out::println);
Copy the code
The parallel flow
int[] nums = {1.2.3.4.5};
// Can be obtained from a serial stream
IntStream.of(nums).parallel();
// From the set
Arrays.asList(nums).parallelStream();
Copy the code

In the middle of operation

Intermediate operations are classified into stateless and stateful operations

stateless
Operation method instructions
map/mapToXxx Do something to all the elements
flatMap/flatMapToXxx Flatten all elements in each element into the current flow
filter Filter, output the elements that meet the condition
peek Similar to forEach, it is often used for print debugging

Map /mapToXxx. Whether map can change the element type depends on the input parameter to the map method

int[] nums = {1.2.3.4.5};
// Map performs one operation on each element. The type of the element cannot be changed because the map input parameter is UnaryOperator
      
       .
      
IntStream.of(nums).map(it -> it + 1).forEach(System.out::println);
// Change the element type
IntStream.of(nums).mapToObj(it -> String.format("[%d]", it)).forEach(System.out::println);

// Map can change the element type, because the map input parameter is Function
      ,>
ArrayList<Test> list1 = Lists.newArrayList(new Test(1."a"), new Test(2."b"));
List<Test2> list2 = list1.parallelStream().map(it -> {
  	return new Test2(it.getId());
}).collect(Collectors.toList());
Copy the code

flatMap/flatMapToXxx

@Data
@AllArgsConstructor
public static class Test {
  	private int id;
  	private int[] data;
}

ArrayList<Test> list1 = Lists.newArrayList(new Test(1.new int[] {1.2.3}), new Test(2.new int[] {4.5.6}));
list1.parallelStream()  / / the Stream < Test > flow
        .flatMapToInt(it -> IntStream.of(it.getData()))  // Convert the data array to an IntStream stream
  			FlatMapToInt (IntStream) : IntStream (IntStream)
        .map(it -> it + 1)
        .forEach(System.out::println);
Copy the code

filter

int[] nums = {1.2.3.4.5};
IntStream.of(nums).filter(it -> it > 3).forEach(System.out::println);
Copy the code

peek

int[] nums = {1.2.3.4.5};
IntStream.of(nums).peek(System.out::println).forEach(System.out::println);
Copy the code
A stateful
Operation method instructions
distinct duplicate removal
sorted The sorting
limit The interception
skip skip

Termination of operations

Operation method instructions
forEach/forEachOrdered ForEach does not guarantee order; forEachOrdered guarantees order
collect/toArray Collect into a collection or array
reduce reduction
min/max/count Find minimum/maximum and total
findAny/findFirst Find either/find the first
allMatch/anyMatch/noneMatch Return true if all matches/true if any matches/true if none matches

Note: Parallel stream calls to forEach are not sequential

reduce

int[] nums = {1.2.3.4.5};
// Reduce the first argument is the initial value, the second argument is the BinaryOperator, input two numbers to return the result of the addition, and then add the last result, finally get the sum of all elements in the entire flow
System.out.println(IntStream.of(nums).reduce(0, Integer::sum));
Copy the code

BigDecimal sum

ArrayList<Test3> list3 = Lists.newArrayList(new Test3(1L.1.5.5), new Test3(2L.2.3.2));
BigDecimal reduce = list3.parallelStream()
        .map(it -> BigDecimal.valueOf(it.getPrice()).multiply(BigDecimal.valueOf(it.getQty())))
        .reduce(BigDecimal.ZERO, BigDecimal::add);
System.out.println(reduce);
Copy the code

The thread pool

By default, parallel streams use their own ForkJoinPool. The number of threads is the number of CPU cores. You can specify a custom thread pool

int[] nums = {1.2.3.4.5};

// Use the default ForkJoinPool
IntStream.of(nums).parallel().forEach(it -> {
    System.out.println(Thread.currentThread().getName() + ":" + it);
});

// Customize a ForkJoinPool
ForkJoinPool pool = new ForkJoinPool(2);
pool.submit(() -> {
    IntStream.of(nums).parallel().forEach(it -> {
        System.out.println(Thread.currentThread().getName() + ":" + it);
    });
});

Thread.currentThread().join();
Copy the code