1 overview of Java8

  • Java8 is a major release of the Java language that was released in March 2014 and is the most revolutionary release since Java5

This release contains more than a dozen new features in languages, compilers, libraries, tools, and JVMS.

2.1 Functional interface

  • A functional interface is an interface that contains only an abstract method, such as java.lang.Runnable and java.util.Comparator

Interface, etc.

  • Java8 provides the @functionalinterface annotation to define a FunctionalInterface, or if the defined interface does not conform to the functional specification

An error.

  • Java8 has added the java.util.function package, which contains common functional interfaces as follows:
The name of the interface Method statement Function is introduced
Runnable void run() A method with no arguments and no return value
Consumer void accept(T t) Perform operations based on the specified parameters
Supplier T get() Get a return value
Function<T,R> R apply(T t) Performs an action based on the specified parameters and returns
Comparator int compare(T o1, T o2) To compare
Predicate boolean test(T t) Checks whether the specified parameter meets the condition

2.1.1 Anonymous inner classes implement functional interfaces

/** * @author * @date 2021/05/31 22:22 */ public FunctionalInterfaceTest {public static void main(String[]) args) { //1. Anonymous inner class: Runnable Runnable = new Runnable() {@override public void run() {Override public void run() { System.out.println(" I am a method with no arguments and no return values!" ); }}; runnable.run(); System.out.println("=================================="); Consumer<String> consumer = new Consumer<String>() { @Override public void accept(String s) { System.out.println(" method with arguments but no return value "+ s); }}; consumer.accept("hello world"); System.out.println("=================================="); Supplier<String> Supplier = new Supplier<String>() {@override public String get() {return "no arguments with return value "; }}; System.out.println(supplier.get()); System.out.println("=================================="); Function<Integer,String> function = new Function<Integer, String>() {@override public String apply(Integer Integer) {return "parameters with returned values" + Integer; }}; System.out.println(function.apply(1)); System.out.println("=================================="); Comparator<Integer> comparator = new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return 0; }}; System. The out. Println (comparator.com pare said (1, 2)); //0 System.out.println("=================================="); Predicate predicate = new Predicate() { @Override public boolean test(Object o) { return false; }}; System.out.println(predicate.test("hello")); //false } }Copy the code

2.1.2 Lambda expressions implement functional interfaces

  • Syntax format :(parameter list) -> {method body; } – The (), parameter type, {}, and return keyword can be omitted.
/** * @author * @date 2021/05/31 22:22 */ public FunctionalInterfaceTest {public static void main(String[]) args) { //1. Name = new Parent/interface type (){method override} Runnable Runnable = () -> system.out.println (" I am a method with no arguments and no return values!" ); runnable.run(); System.out.println("=================================="); Consumer<String> Consumer = s -> system.out.println (" method with arguments but no return value "+ s); consumer.accept("hello world"); System.out.println("=================================="); Supplier<String> Supplier = () -> "no arguments return value "; System.out.println(supplier.get()); System.out.println("=================================="); Function<Integer,String> Function = Integer -> "" + Integer; System.out.println(function.apply(1)); System.out.println("=================================="); Comparator<Integer> comparator = (o1, o2) -> 0; System. The out. Println (comparator.com pare said (1, 2)); //0 System.out.println("=================================="); Predicate predicate = o -> false; System.out.println(predicate.test("hello")); //false } }Copy the code

2.1.3 Method references implement functional interfaces

  • A method reference refers to the invocation of a method that is referred to by its name without providing the method body for the method reference

Execute to a functional interface.

  • Method references use a pair of colons :: to connect a class or object to a method name, usually as follows:
    • Object that references ObjectName :: MethodName
    • The static method of the class references ClassName :: StaticMethodName
    • Nonstatic methods of the class refer to ClassName :: MethodName
    • Constructor reference ClassName :: new
    • Array reference TypeName[] :: new
  • A method reference is a simplified representation of a lambda expression in a particular scenario, which can further simplify code writing and make it more

Compact and concise, thus reducing redundant code

(1) Non-static method references to objects

Object that references ObjectName :: MethodName

/** * @author * @date 2021/05/31 23:03 */ public class MethodReferenceTest {public static void main(String[] args) {  Person person = new Person("yangzhen",24); Runnable Runnable = new Runnable() {@override public void run() {Override public void run() { person.show(); }}; runnable.run(); System.out.println("=================================="); Runnable runnable1 = () -> person.show(); runnable1.run(); System.out.println("=================================="); Runnable runnable2 = Person ::show; runnable2.run(); System.out.println("=================================="); //4. Call Consumer<String> Consumer = new Consumer<String>() {@override public void accept(String s) { person.setName(s); }}; consumer.accept("yangzhen2"); System.out.println(person); // yangzhen2 24 System.out.println("=================================="); Consumer<String> Consumer = s -> person.setName(s); Consumer<String> Consumer = s -> person.setName(s); consumer.accept("yangzhen3"); System.out.println(person); // yangzhen3 24 System.out.println("=================================="); Consumer<String> Consumer2 = Person ::setName; consumer.accept("yangzhen4"); System.out.println(person); // yangzhen4 24 } }Copy the code

(2) class static method references

The static method of the class references ClassName :: StaticMethodName

/** * @author * @date 2021/05/31 23:43 */ public class MethodReferenceTest {public static void main(String[] args) { <Integer> Comparator = new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return Integer.compare(o1,o2); }}; System. The out. Println (comparator.com pare said (10, 20)); //-1 Comparator<Integer> comparator1 = (o1,o2) -> Integer.compare(o1,o2); System. The out. Println (comparator1.com pare said (10, 20)); //-1 Comparator<Integer> comparator2 = Integer::compare; System. The out. Println (comparator.com pare said (20, 10)); //1 // custom return Comparator<Integer> comparator3 = (o1, O2) -> {return o1 >= O2? o1:o2; }; System. The out. Println (comparator3.com pare said (10, 11)); / / 11}}Copy the code

(3) class non-static method references

Nonstatic methods of the class refer to ClassName :: MethodName

The method can be more abstract when one of the argument objects is called as a call object

/** * @author * @date 2021/05/31 23:43 */ public class MethodReferenceTest {public static void main(String[] args) { <Integer> Comparator = new Comparator<Integer>() {@override public int compare(Integer o1, Integer o2) { return o1.compareTo(o2); }}; System. The out. Println (comparator4.com pare said (20, 10)); //1 Comparator<Integer> comparator5 = (o1, o2) -> o1.compareTo(o2); System. The out. Println (comparator5.com pare said (20, 10)); <Integer> comparator6 = Integer::compareTo; System. The out. Println (comparator6.com pare said (10, 20)); / / - 1}}Copy the code

(4) Constructor references

Constructor reference ClassName :: new

/** * @author * @date 2021/05/31 23:43 */ public class MethodReferenceTest {public static void main(String[] args) {  Supplier<Person> supplier = new Supplier<Person>() { @Override public Person get() { return new Person(); }}; System.out.println(supplier.get()); //Person{name='null', age=0} Supplier<Person> supplier1 = ()-> new Person(); System.out.println(supplier1.get()); //Person{name='null', age=0} Supplier<Person> supplier2 = Person::new; System.out.println(supplier2.get()); //Person{name='null', age=0}Copy the code

(4) Array reference

Array reference TypeName[] :: new

/** * @author * @date 2021/05/31 23:43 */ public class MethodReferenceTest {public static void main(String[] args) {  Function<Integer,Person[]> function = new Function<Integer, Person[]>() { @Override public Person[] apply(Integer integer) { return new Person[integer]; }}; System.out.println(Arrays.toString(function.apply(3))); //[null, null, null] Function<Integer,Person[]> function1 = integer -> new Person[integer]; System.out.println(Arrays.toString(function1.apply(4))); //[null, null, null, null] Function<Integer,Person[]> function2 = Person[]::new; System.out.println(Arrays.toString(function2.apply(5))); //[null, null, null, null, null] } }Copy the code

2.2 the Stream interface

2.2.1 Basic Concepts

  • The java.util.stream. stream interface is a collection enhancement that enables complex lookup, filtering, and filtering of collection elements

Such operations.

  • The Stream interface uses Lambda expressions to greatly improve programming efficiency and program readability, and it provides both serial and parallel programming

Concurrent mode can make full use of the advantages of multi-core processors.

2.2.2 Procedure

  • Create a Stream to retrieve a Stream from a data source.
  • Converts a Stream, returning a new Stream object each time.
  • Aggregate the Stream and produce the result.

2.2.3 Creation Method

  • Method 1: Get the Stream by calling the collection’s default method, e.g. : Default Stream Stream ()
  • Static IntStream stream(int[] array) static IntStream stream(int[] array)
  • Static Stream of(T… values)
  • Static Stream generate(Supplier

s)

2.2.4 Intermediate Operations

  • The common methods of screening and slicing are as follows:
Method statement Function is introduced
Stream filter(Predicate<? super T> predicate) Returns a stream containing matching elements
Stream distinct() Returns a stream that contains no repeating elements
Stream limit(long maxSize) Returns a stream that does not exceed a given number of elements
Stream skip(long n) Returns the stream after the first n elements are discarded
  • Common mapping methods are as follows:
Method statement Function is introduced
Stream map(Function<? super T,? extends R> mapper) Returns a stream composed of each processed element
Stream flatMap(Function<? super T,? extends Stream<? extends R>> mapper) Returns a stream composed of each replaced element and combines all streams into a single stream
  • Common sorting methods are as follows:
Method statement Function is introduced
Stream sorted() Returns a naturally ordered stream of elements
Stream sorted(Comparator<? super T> comparator) Returns a comparator sorted stream of elements

2.2.5 Terminating the operation

  • The common methods of matching and searching are as follows:
Method statement Function is introduced
Optional findFirst() Returns the first element of the stream
boolean allMatch(Predicate<? super T> predicate) Returns whether all elements match
boolean noneMatch(Predicate<? super T> predicate) Returns no element matches
Optional max(Comparator<? super T> comparator) Returns the maximum element based on the comparator
Optional min(Comparator<? super T> comparator) Returns the smallest element based on the comparator
long count() Returns the number of elements
void forEach(Consumer<? super T> action) Perform operations on each element in the flow
  • Common methods of protocol are as follows:
Method statement Function is introduced
Optional reduce(BinaryOperator accumulator) Returns the combined element value
  • Common methods of collection are as follows:
Method statement Function is introduced
<R,A> R collect(Collector<? super T,A,R> collector) Elements are processed using collectors

2.2.6 Code cases

(1) Stream implements filtering and printing of collection elements

Public class ListPersonTest {public static void main(String[]) {public static void main(String[]); args) { //1. List<Person> List = new LinkedList<>(); list.add(new Person("AAA",16)); list.add(new Person("BBB",13)); list.add(new Person("CCC",22)); list.add(new Person("DDD",21)); list.add(new Person("DDD",21)); list.add(new Person("EEE",30)); for (Person person : list) { System.out.println(person); } System.out.println("=================================="); List<Person> list2 = new LinkedList<>(); for (Person person : list) { if (person.getAge() >= 18) { list2.add(person); } } for (Person person : list2) { System.out.println(person); } System.out.println("=================================="); List.stream ().filter(new Predicate<Person>() {@override public Boolean test(Person Person) { return person.getAge() >= 18; } }).forEach(new Consumer<Person>() { @Override public void accept(Person person) { System.out.println(person); }}); System.out.println("=================================="); List.stream ().filter(person -> person.getage () >= 18).foreach (person -> System.out.println(person)); System.out.println("=================================="); Filter (person -> person.getage () >= 18).foreach (system.out ::println); }}Copy the code

(2) Stream implements slicing and mapping of set elements

public class ListPersonTest { public static void main(String[] args) { List<Person> list = new LinkedList<>(); list.add(new Person("AAA",16)); list.add(new Person("BBB",13)); list.add(new Person("CCC",22)); list.add(new Person("DDD",21)); list.add(new Person("DDD",21)); list.add(new Person("EEE",30)); List.stream ().skip(2).limit(3).foreach (system.out ::println); List.stream ().map(new Function<Person, Integer>() { @Override public Integer apply(Person person) { return person.getAge(); } }).forEach(System.out::println); list.stream().map(person -> person.getAge()).forEach(System.out::println); list.stream().map(Person::getAge).forEach(System.out::println); }}Copy the code

(3) Stream implements sorting of collection elements

public class ListPersonTest { public static void main(String[] args) { List<Person> list = new LinkedList<>(); list.add(new Person("AAA",16)); list.add(new Person("BBB",13)); list.add(new Person("CCC",22)); list.add(new Person("DDD",21)); list.add(new Person("DDD",21)); list.add(new Person("EEE",30)); list.stream().sorted((p1,p2)-> p1.getAge() - p2.getAge()).forEach(System.out::println); list.stream().sorted(Comparator.comparingInt(Person::getAge)).forEach(System.out::println); }}Copy the code