• Four functional interfaces

    1. Function – A functional interface with parameters and return values
    2. Predicate interface – Takes parameters and returns Boolean values
    3. Consumer Consumer interface – with parameters and no return value
    4. Supplier producer interface – Takes no parameters and has a return value
  • Stream computing

  • ForkJoin branch merged

  • Future asynchronous callback

Four functional interfaces

Simplified coding techniques: Lambda expression, chain programming, functional interface, Stream calculation.

As long as the interface is functional, it can be simplified using Lambda expressions

Functional interface: An interface that has only one method, such as the Runnable interface, and a parameter to forEach that is a functional interface of consumer type

The java.util.Function package has four basic functional interfaces

  • Function
  • Consumer
  • Predicate
  • Supplier
========== Runnable interface ========== @functionalInterface Public interface Runnable {/** * When an object implements interface <code>Runnable</code> is used * to create a thread, starting the thread causes the object's * <code>run</code> method to be called in that separately executing * thread. * <p> * The general contract of the method <code>run</code> is that it may * take any action whatsoever. * * @see java.lang.Thread#run() */ public abstract void run(); } ========== foreach consumer = =========== @override public void foreach (consumer <? super E> action) { Objects.requireNonNull(action); final int expectedModCount = modCount; @SuppressWarnings("unchecked") final E[] elementData = (E[]) this.elementData; final int size = this.size; for (int i=0; modCount == expectedModCount && i < size; i++) { action.accept(elementData[i]); } if (modCount ! = expectedModCount) { throw new ConcurrentModificationException(); }} =========== Consumer Consumer interface ============= @functionalInterface Public Interface Consumer<T> {/** * Performs this operation on the given argument. * * @param t the input argument */ void accept(T t); /** * Returns a composed {@code Consumer} that performs, in sequence, this * operation followed by the {@code after} operation. If performing either * operation throws an exception, it is relayed to the caller of the * composed operation. If performing this operation throws an exception, * the {@code after} operation will not be performed. * * @param after the operation to perform after this operation * @return a composed {@code Consumer} that performs in sequence this * operation followed by the {@code after} operation *  @throws NullPointerException if {@code after} is null */ default Consumer<T> andThen(Consumer<? super T> after) { Objects.requireNonNull(after); return (T t) -> { accept(t); after.accept(t); }; }}Copy the code
1.Function interface

instructions

  • The apply method takes a parameter t and returns a parameter R
  • This can be simplified using Lambda expressions

The source code

/** * Represents a function that accepts one argument and produces a result. * * <p>This is a <a href="package-summary.html">functional interface</a> * whose functional method is {@link #apply(Object)}. * * @param <T> The type of the input to the function * @param <R> the type of the result of the function * * @since 1.8 */ @FunctionalInterface public interface Function<T, R> { /** * Applies this function to the given argument. * * @param t the function argument * @return the function result  */ R apply(T t); ====== ** * Returns a composed function that applies first the {@code before} * function to its input, and then applies this function to the result. * If evaluation of either function throws an exception, it is relayed to * the caller of the composed function. * * @param <V> the type of input to the {@code before} function,  and to the * composed function * @param before the function to apply before this function is applied * @return a composed function that first applies the {@code before} * function and then applies this function * @throws NullPointerException if before is null * * @see #andThen(Function) */ default <V> Function<V, R> compose(Function<? super V, ? extends T> before) { Objects.requireNonNull(before); return (V v) -> apply(before.apply(v)); } /** * Returns a composed function that first applies this function to * its input, and then applies the {@code after} function to the result. * If evaluation of either function throws an exception, it is relayed to * the caller of the composed function. * * @param <V> the type of output of the {@code after} function,  and of the * composed function * @param after the function to apply after this function is applied * @return a composed  function that first applies this function and then * applies the {@code after} function * @throws NullPointerException if after is null * * @see #compose(Function) */ default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) { Objects.requireNonNull(after); return (T t) -> after.apply(apply(t)); } /** * Returns a function that always returns its input argument. * * @param <T> the type of the input and output objects to the function * @return a function that always returns its input argument */ static <T> Function<T, T> identity() { return t -> t; }}Copy the code

For example,

package study_function; import java.util.function.Function; Public class Demo1 {public static void main(String[] args) {// public static void main(String[] args) {// Public static void main(String[] args) {// Function<String,String>() { @Override public String apply(String str) { return str; }}; Function1 = (STR)->{return STR; }; Function function2 = str-> {return str; }; System.out.println(function.apply("xiaosi")); // Output xiaosi system.out.println (function1.apply("xiaosi")); // Output xiaosi system.out.println (function1. // Output xiaosi system.out.println (function2.apply("xiaosi")); // Output xiaosi system.out.println (function2. // output xiaosi}}Copy the code
2.Predicate interfaces

instructions

  • Stereotyped interface
  • Takes an argument and returns a Boolean value

The source code

/** * Represents a predicate (boolean-valued function) of one argument. * * <p>This is a <a href="package-summary.html">functional interface</a> * whose functional method is {@link #test(Object)}. * * @param <T> The type of the input to the predicate ** @since 1.8 */ @functionalInterface public interface predicate <T> {/** * Evaluates this predicate on the given argument. * * @param t the input argument * @return {@code true} if the input argument matches the predicate, * otherwise {@code false} */ boolean test(T t); /** * Returns a composed predicate that represents a short-circuiting logical * AND of this predicate and another. When evaluating the composed * predicate, if this predicate is {@code false}, then the {@code other} * predicate is not evaluated. * * <p>Any exceptions thrown during evaluation of either predicate are relayed * to the caller; if evaluation of this predicate throws an exception, the * {@code other} predicate will not be evaluated. * * @param other a predicate that will be logically-ANDed with this  * predicate * @return a composed predicate that represents the short-circuiting logical * AND of this predicate and the  {@code other} predicate * @throws NullPointerException if other is null */ default Predicate<T> and(Predicate<? super T> other) { Objects.requireNonNull(other); return (t) -> test(t) && other.test(t); } /** * Returns a predicate that represents the logical negation of this * predicate. * * @return a predicate that represents the logical negation of this * predicate */ default Predicate<T> negate() { return (t) -> ! test(t); } /** * Returns a composed predicate that represents a short-circuiting logical * OR of this predicate and another. When  evaluating the composed * predicate, if this predicate is {@code true}, then the {@code other} * predicate is not evaluated. * * <p>Any exceptions thrown during evaluation of either predicate are relayed * to the caller; if evaluation of this predicate throws an exception, the * {@code other} predicate will not be evaluated. * * @param other a predicate that will be logically-ORed with this * predicate * @return a composed predicate that represents the short-circuiting logical * OR of this predicate and the {@code other} predicate * @throws NullPointerException if other is null */ default Predicate<T> or(Predicate<? super T> other) { Objects.requireNonNull(other); return (t) -> test(t) || other.test(t); } /** * Returns a predicate that tests if two arguments are equal according * to {@link Objects#equals(Object, Object)}. * * @param <T> the type of arguments to the predicate * @param targetRef the object reference with which to compare for equality, * which may be {@code null} * @return a predicate that tests if two arguments are equal according * to {@link Objects#equals(Object, Object)} */ static <T> Predicate<T> isEqual(Object targetRef) { return (null == targetRef) ? Objects::isNull : object -> targetRef.equals(object); }}Copy the code

For example,

package study_function; import java.util.function.Predicate; /** * Public class Demo2_predicate {public static void main(String[] args) {// General Predicate<String> predicate = new Predicate<String>() { @Override public boolean test(String s) { if(! s.isEmpty() && s.length() >= 3){ return true; } return false; }}; Predicate1 = (s)->{if((! s.isEmpty()) && (s.length() >= 3)) { return true; } return false; }; System.out.println(predicate.test("xiaosi")); // true System.out.println(predicate1.test("xiaosi")); // true } }Copy the code
3.Consumer Consumer interface

instructions

  • Accepts an argument with no return value

The source code

/** * Represents an operation that accepts a single input argument and returns no * result. Unlike most other functional  interfaces, {@code Consumer} is expected * to operate via side-effects. * * <p>This is a <a href="package-summary.html">functional interface</a> * whose functional method is {@link #accept(Object)}. * * @param <T> the type of the input to the Operation ** @since 1.8 */ @functionalInterface Public Interface Consumer<T> {/** * Performs this operation on the given argument. * * @param t the input argument */ void accept(T t); /** * Returns a composed {@code Consumer} that performs, in sequence, this * operation followed by the {@code after} operation. If performing either * operation throws an exception, it is relayed to the caller of the * composed operation. If performing this operation throws an exception, * the {@code after} operation will not be performed. * * @param after the operation to perform after this operation * @return a composed {@code Consumer} that performs in sequence this * operation followed by the {@code after} operation *  @throws NullPointerException if {@code after} is null */ default Consumer<T> andThen(Consumer<? super T> after) { Objects.requireNonNull(after); return (T t) -> { accept(t); after.accept(t); }; }}Copy the code

For example,

package study_function; import java.util.function.Consumer; Public class Demo3_consumer {public static void main(String[] args) {public static void main(String[] args) Consumer<String> consumer = new Consumer<String>() { @Override public void accept(String s) { System.out.println(" consumed ==== "+ s); }}; Consumer<String> consumer1 = (STR)->{system.out. println(" Consumer === "" + STR); }; consumer.accept("xiaosi"); ==== "xiaosi consumer1.accept("si"); // consume ==== si}}Copy the code
4.Supplier Producer interface

instructions

  • No input argument, return value

The source code

package java.util.function;

/**
 * Represents a supplier of results.
 *
 * <p>There is no requirement that a new or distinct result be returned each
 * time the supplier is invoked.
 *
 * <p>This is a <a href="package-summary.html">functional interface</a>
 * whose functional method is {@link #get()}.
 *
 * @param <T> the type of results supplied by this supplier
 *
 * @since 1.8
 */
@FunctionalInterface
public interface Supplier<T> {

    /**
     * Gets a result.
     *
     * @return a result
     */
    T get();
}

Copy the code

B, Stream calculation

What is Stream computing

  • Collections are commonly used to store sets of numbers, whereas forSome processing of set data(like filtering collection data) can be handled using a Stream Stream
  • The Stream interface under the java.util.tream package supports a series of elements for sequential and parallel aggregation operations
  • A Stream can be combined with four functional interfaces for data processing (method arguments support functional interfaces)

use

  • Set. The stream ()You can turn a collection object into a stream object and call some of the stream object’s methods for data manipulation
  • Commonly used method

filter(Predicate<? Super T> predicate) returns a stream consisting of the elements of the stream that match this given predicate.

  • Count () returns the number of elements in this stream.
  • forEach(Consumer
    action) performs operations on each element of the stream.
  • sorted(Comparator
    comparator) returns a stream consisting of the elements of the stream, sorted by the provided comparator.
  • map(Function
    mapper) returns a flow consisting of the results of the elements to which the given function is applied.
  • sorted(Comparator
    comparator) returns a stream consisting of the elements of the stream, sorted by the provided comparator.

For example,

package study_stream; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Stream; Public class Demo1 {public static void main(String[] args) {User user1 = new User("xiaosi1",20,18000); User user2 = new User("xiaosi2",21,19000); User user3 = new User("xiaosi3",23,20000); User user4 = new User("xiaosi4",24,21000); User user5 = new User("xiaosi5",25,22000); User user6 = new User("xiaosi6",26,23000); List<User> list = Arrays.asList(user1,user2,user3,user4,user5,user6); // 1. forEach list.stream().forEach((user)->{ System.out.println(user); }); list.stream().close(); System.out.println("==================="); // Filter age above 21, User list.stream().filter ((user)->{return user.getsalary () > 20000; }). filter((user)->{return user.getAge()>= 21; }). forEach(System.out::println); list.stream().close(); System.out.println("=================="); // 3. map(Function<? super T,? Extends R> mapper) // Returns a flow consisting of the results of the elements to which the given function is applied. // salary sort list.stream().filter ((user)->{return user.getsalary () < 20000; }). map((user)->{ return user.getSalary() + 2000; }). // Return sorted((u1,u2)->{return u1.compareTo(u1); }). forEach(System.out::println); list.stream().close(); } } class User{ private String name; private int age; private int salary; public User(String name, int age, int salary) { this.name = name; this.age = age; this.salary = salary; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getSalary() { return salary; } public void setSalary(int salary) { this.salary = salary; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + ", salary=" + salary + '}'; }} output: User{name='xiaosi1', age=20, salary=18000} User{name='xiaosi2', age=21, salary=19000} User{name='xiaosi3', age=23, salary=20000} User{name='xiaosi4', age=24, salary=21000} User{name='xiaosi5', age=25, salary=22000} User{name='xiaosi6', age=26, salary=23000} =================== User{name='xiaosi4', age=24, salary=21000} User{name='xiaosi5', age=25, salary=22000} User{name='xiaosi6', age=26, salary=23000} ================== 20000 21000Copy the code

ForkJoin branch merged

concept

  • Call the method from the FokeJoinPool instance

    • void execute(ForkJoinTask
      task) to perform a given task asynchronously.
    • Void execute(Runnable Task) executes the given command at some future time.
    • T Submit (ForkJoinTask) Submits a ForkJoinTask to execute. Return the current task and get the return value by calling get()
  • A method that executes a task is ForkJoinTask

    • RecursiveAction Recursive event with no return value
    • RecursiveTask a RecursiveTask with a return value
  • MyTask inherits ForkJoinTask, overriding the compute method

  • The last execution

    • ForkJoinPool forkJoinPool = new ForkJoinPool();
    • ForkJoinTask res = forkJoinPool.submit(myTask);
    • System.out.println(res.get());

    For example,

============ MyRecursiveTask ======== package study_fokejoin; import java.util.concurrent.AbstractExecutorService; import java.util.concurrent.ForkJoinTask; import java.util.concurrent.RecursiveTask; Public class MyRecursiveTask extends RecursiveTask<Long> {private Long start =  1L; private Long end; Private Long Temp = 10000L; long sum = 0L; public MyRecursiveTask(Long start, Long end) { this.start = start; this.end = end; } @override protected Long compute() {if((end-start) < temp){for (Long I = start; i <= end; i++) { sum += i; } return sum; } // ForkJoin else{long mid = (start + end) /2; MyRecursiveTask task1 = new MyRecursiveTask(start,mid); task1.fork(); MyRecursiveTask task2 = new MyRecursiveTask(mid+1,end); task2.fork(); Long sum = task1.join() + task2.join(); return sum; } } } ============ Test =============== package study_fokejoin; import java.util.concurrent.ExecutionException; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinTask; import java.util.stream.LongStream; public class Test { public static void main(String[] args) throws ExecutionException, InterruptedException {// Use FokrJoin to calculate MyRecursiveTask task = new MyRecursiveTask(1L,10_0000_0000L); ForkJoinPool forkJoinPool = new ForkJoinPool(); ForkJoinTask<Long> res = forkJoinPool.submit(task); System.out.println(res.get()); Println (longstream.rangeclosed (1L, 10_0000_0000L).parallel().reduce(0, Long::sum)); }}Copy the code

Asynchronous callback

concept

  • Similar to Ajax techniques, asynchronous execution, success callback, failure callback can be performed.
  • The java.util.concurrent package contains the interface Future
    • Implement subclasses: CompletableFuture, CountedCompleter, ForkJoinTask, FutureTask, RecursiveAction, RecursiveTask, SwingWorker
  • CompletableFuture has static methods
    • No result is returned

  • Return result

For example,

package study_future; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; public class Demo1 { public static void main(String[] args) throws ExecutionException, InterruptedException { test2(); } // 1. Asynchronous static void test1() throws ExecutionException, InterruptedException { CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(()->{ try { TimeUnit.SECONDS.sleep(3); System.out.println(" Asynchronous task executed!! ") ); } catch (Exception e) { e.printStackTrace(); } finally { } }); System.out.println("xiaosi1"); completableFuture.get(); } // 2. Throws ExecutionException with a return value. InterruptedException { CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(()->{ int num = 10 / 0; try { TimeUnit.SECONDS.sleep(3); return 1; } catch (Exception e) { e.printStackTrace(); return -1; }}); System.out.println("xiaosi2"); completableFuture.whenCompleteAsync((t,u)->{ System.out.println(t+"=====> " + t); Println (u+"=====> "+ u); // Return system.out. println(u+"=====>" + u); // Failed message system.out.println (" Asynchronous execution with return value!" ); }). Exceptionally ((e)->{// exception catch e.printStackTrace(); return 404; }).get(); }}Copy the code