day_25Lambda expression, functional interface

Keywords: Lambda Functional Programming

1. Lambda

1.1 general

Lambda expression is a function without name, which can also be called closure. It is the most important new feature released by Java 8. It is essentially an anonymous inner class or a piece of code that can be passed

And the arrow function

1.2 why use Lambda expressions

Lambda expression is a short form of anonymous inner class, which makes the program simpler and clearer, and improves the programming efficiency

1.3 comparison with anonymous inner classes

		//2 anonymous inner class
		forEach(arr,new Array(){
			
			public void m1(int i){
				System.out.println(i +"-===-");
			}
		});
		//3Lambda expression
		forEach(arr,(i)->System.out.println(i+1+"+++"));

1.4 grammatical structure

Optional type declaration: there is no need to declare parameter types, and the compiler can uniformly identify parameter values

Optional parameter parentheses: one parameter does not need to define parentheses, but multiple parameters need to define parentheses

Optional curly braces: if the body contains a statement, curly braces are not required

        If you don't write {} return, you can't write parentheses

Optional return keyword: if the body has only one expression return value, the compiler will automatically return the value. Curly braces need to indicate that the expression returns a value

        If there is only one statement and it is a return value statement, you can not write return or {}

        If you write {}, you must write return and;

        If there are multiple statements, you must write {} return and;

1.5 cases

1 does not require parameters, and the return value is 5

()->5

2 receives a parameter (numeric type) and returns twice its value

x->x*2

3 receive two parameters (numbers) and return their difference

(x,y)->x-y

1.6 practice

package day_27text;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class Text02 {

	public static void main(String[] args) {
		List<Integer>list = new ArrayList<Integer>();
		list.add(1);
		list.add(2);
		list.add(3);
		//Conventional writing
		//for(Integer integer :list){
		//System.err.println(integer);
		//}
		
		//Anonymous inner class writing
		//list.forEach(new Consumer<Integer>(){
		//public void accept(Integer t){
		//System.out.println(t);
		//}
		//});
		
		//Lambda writing
		list.forEach(x->System.out.println(x));
	}

}
package day_27text;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Text03 {

	public static void main(String[] args) {
		List<Integer>list = new ArrayList<Integer>();
		list.add(11);
		list.add(2);
		list.add(3);
		//Cillections.sort(list,new Comparator<Integer>(){
		//public int compare(Inreger o1,Integer o2){
		//return o2 - o1;
		//}
		//});
		
		Collections.sort(list,(x,y) -> y - x);
		
		System.out.println(list);
	}

}
class B{
	public boolean equals(Object obj){
		return false;
	}
}

2. Functional interface

2.1 introduction

        Expected Functional Interface

         Its essence is an interface with only one abstract method, but it can have multiple non abstract methods

         The core goal is to provide better support for the use of Lambda expression and further achieve the goal of functional programming. The programming efficiency can be greatly improved by using functional programming

         It can be implicitly converted to a Lambda expression

2.2 features

A functional interface is an interface that formulates only one abstract method

Can contain one or more static or default methods

The special annotation, namely @ Functional Interface, checks whether it is a Functional Interface or not

If there are two or more abstract methods, they cannot be used as functional interfaces, and the @ Functional Interface annotation cannot be added

If there is only one abstract method, the @ Functional Interface annotation can be used as a Functional Interface with or without it

2.3 code implementation

2.3.1 no participation

public class FunInterface_01 {
	// Custom static method to receive interface object
	public static void call(MyFunctionInter func) {
		// Calling member methods within an interface
		func.printMessage();
	}

	public static void main(String[] args) {
		// The first call: directly call the custom call method and pass in the function
		FunInterface_01.call(() -> {
			System.out.println("HelloWorld!!!");
		});

		// The second call: first create a function object, similar to the internal class object that implements the interface
		MyFunctionInter inter = () -> {
			System.out.println("HelloWorld2!!!!");
		};
		// Call the method of this implementation
		inter.printMessage();
	}
}
// Functional interface
@FunctionalInterface
interface MyFunctionInter {
	void printMessage();
}

2.3.2 with reference

public class FunInterface_02 {
	// Custom static method to receive interface object
	public static void call(MyFunctionInter_02 func, String message) {
		// Calling member methods within an interface
		func.printMessage(message);
	}

	public static void main(String[] args) {
		// Call the data to be passed
		String message = "Parametric functional interface call!!!";

		// The first call: directly call the custom call method, pass in the function, and pass in the data
		FunInterface_02.call((str) -> {
			System.out.println(str);
		}, message);

		// The second call: first create a function object, similar to the internal class object that implements the interface
		MyFunctionInter_02 inter = (str) -> {
			System.out.println(str);
		};
		// Call the method of this implementation
		inter.printMessage(message);
	}
}

// Functional interface
@FunctionalInterface
interface MyFunctionInter_02 {
	void printMessage(String message);
}

2.4 JDK comes with common functional interfaces

2.4.1 supplier < T > interface

The supplier < T > interface represents the result supplier, so it has a return value and can obtain data

There is a get method for getting data

public class _03_JdkOwn_01 {
	private static String getResult(Supplier<String> function) {
		return function.get();
	}

	public static void main(String[] args) {
		// 1
		String before = "Zhang San";
		String after = "Hello";
		// Concatenate two strings
		System.out.println(getResult(() -> before + after));

		// 2 / / create a Supplier container and declare it as_ 03_JdkOwn type
		// At this time, the construction method of the object is not called, that is, the object is not created
		Supplier<_03_JdkOwn_01> sup = _03_JdkOwn_01::new;
		_03_JdkOwn_01 jo1 = sup.get();
		_03_JdkOwn_01 jo2 = sup.get();

	}

	public _03_JdkOwn_01() {
		System.out.println("The construction method is executed");
	}
}

2.4.2consumer < T > interface

Consumer < T > interface consumer interface, so no return value is required

There is an accept(T) method, which is used to perform consumption operations. You can do any operation on a given parameter t

public class _04_JdkOwn_02 {
	private static void consumeResult(Consumer<String> function, String message) {
		function.accept(message);
	}

	public static void main(String[] args) {
		// Parameters passed
		String message = "Consume some content!!!";
		// Call method
		consumeResult(result -> {
			System.out.println(result);
		}, message);
	}
}

2.4.3 function < T, R > interface

The function < T.R > interface represents a function that receives a parameter and generates a result

As the name suggests, it is a function operation

There is a happy (T) method. There is no specific operation in the Function. The specific operation needs to be specified for it. Therefore, the result of the specific return value of apply depends on the incoming Lambda expression

public class _05_JdkOwn_03 {
	// Function < parameter, return value >
	public static void convertType(Function<String, Integer> function,
			String str) {
		int num = function.apply(str);
		System.out.println(num);
	}

	public static void main(String[] args) {
		// Parameters passed
		String str = "123";
		// S indicates that parameters need to be passed. You can also write (s)
		convertType(s -> {
			int sInt = Integer.parseInt(s);
			return sInt;
		}, str);
	}
}

2.4.4 predict < T > interface

Predicate < T > interface assertion interface

Just make some judgments, and the return value is boolean

There is a boolean test(T) method to verify whether the incoming data meets the judgment conditions and return the boolean type

public class _06_JdkOwn_04 {
	// Custom method, and Predicate receives String type
	public static void call(Predicate<String> predicate, String isOKMessage) {
		boolean isOK = predicate.test(isOKMessage);
		System.out.println("isOK Yes:" + isOK);
	}

	public static void main(String[] args) {
		// Parameters passed in
		String input = "ok";
		call((String message) -> {
			// Case insensitive comparison. If it is ok, it returns true; otherwise, it returns false
			if (message.equalsIgnoreCase("ok")) {
				return true;
			}
			return false;
		}, input);
	}
}

3. Method reference and constructor call

2.5 object call object

package day_27text03;

import java.util.function.Supplier;

/**
 * Object reference:: member method name
 * 
 * Requirement: you need to select the corresponding functional interface according to the input and output parameters of the calling method
 *
 * @author Learn bald Zhang
 *@Date 2021 3:15:19 am, November 3
 */
public class Text01 {
	public static void main(String[] args) {
		Integer i1 = new Integer(123);
		// Conventional lambda writing
		Supplier<String> su = () -> i1.toString();
		System.out.println(su.get());

		// Method reference writing
		su = i1::toString;
		System.out.println(su.get());
	}
}

2.6 class name calling static

package day_27text03;

import java.util.function.BiFunction;
import java.util.function.Function;

/**
 *Class name: static
 *
 * @author Learn bald Zhang
 *@Date 2021 3:17:09 am, November 3
 */
public class Text02 {
	public static void main(String[] args) {

		Function<String, Integer> fun = Integer::parseInt;
		System.out.println(fun.apply("123"));

		fun = new Function<String, Integer>() {
			@Override
			public Integer apply(String t) {
				// TODO Auto-generated method stub
				return null;
			}
		};

		fun = x -> Integer.parseInt(x);
		fun = Integer::parseInt;

		// The first two are input parameters and the third is return value
		BiFunction<Integer, Integer, Integer> bif = Integer::max;
		System.out.println(bif.apply(123, 323));
		test((B x) -> System.out.println(x));
	}

	public static void test(A a) {

	}
}
interface A {
	public void m1(B b);
}

class B {

}

2.7 class name calling object

package day_27text03;

import java.util.function.BiPredicate;

/**
 * Class name: member method name
 *
 * @author Learn bald Zhang
 *@Date 2021 3:22:42 am, November 3
 */
public class Text03 {
	public static void main(String[] args) {
		BiPredicate<String, String> bp = String::equals;
		System.out.println(bp.test("abc", "abc"));
	}
}

2.8 construction method call

package day_27text;

import java.util.function.Function;
import java.util.function.Supplier;

public class Text04 {

	public static void main(String[] args) {
		//Nonparametric structure
		Supplier<Object> objSi = Object::new;
		System.out.println(objSi.get());
		
		//Parametric structure
		Function<String,Integer> function = Integer::new;
		System.out.println(function.apply("123"));
		//new Integer("123");

	}

}

2.9 array reference

package day_27text;

import java.util.function.Function;

public class Text05 {

	public static void main(String[] args) {
		Function<Integer,Integer[]>function = Integer[]::new;
		Integer[] arr =function.apply(10);
		
		for(Integer integer:arr){
			System.out.println(integer);
		}

	}

}

4.Stream API

4.1 concept description

Data channel, pipeline, used to operate the element sequence generated by data source (set, array, etc.)

Collection is about data, and flow is about computation

That is, a set of API s used to process arrays and collections

4.2 features

Stream is not a data structure and has no internal storage. It will not store elements by itself

Streams do not change the source object. Instead, they return a new Stream that holds the result

Stream operations are delayed. This means that they wait until the results are needed

Index access is not supported

Delay calculation

Support parallelism

It is easy to generate data or collections

Support filtering, searching, conversion, summary, aggregation and other operations

4.3 application scenarios

Stream computing requires delayed computing and more convenient parallel computing

More flexible and concise collection processing scenarios

4.4 code implementation

4.4.1 description of operation mechanism

Stream is divided into source, intermediate operation and termination operation

The source of a stream can be an array, a collection, a generator method, an I/O channel, and so on

A stream can have zero or more intermediate operations. Each intermediate operation will return a new stream for the next operation. A stream will only have one termination operation

        Intermediate operations are also called transformation operators

Only when a Stream encounters a termination operation, its data source will start to perform a traversal operation

        The termination operation is also called action operator action

        Because the return value of the action operator is no longer stream, the calculation is terminated

        Only when we encounter the action operator can we really calculate

4.4.2 method of creating flow

package day_27text04;

import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * Generate flow
 *
 * @author Learn bald Zhang
 *@Date 2021 3:37:07 am, November 3
 */
public class Text01 {
	public static void main(String[] args) {
		// 1 convert array to stream
		String[] strings = { "q", "w", "e", "r" };
		Stream<String> stream1 = Stream.of(strings);

		// 2 through set
		// Arrays.asList: convert arrays to collections
		List<String> list = Arrays.asList(strings);
		stream1 = list.stream();
		
		// 3. Create through generate of Stream
		// However, it is an infinite stream (infinite), so it is often used in combination with limit to limit the maximum number
		// The generate parameter is a Supplier, and the Supplier has a get method to get data
		// The return value of the get method will be saved to the stream as data. The following program means that the data in the stream is 1
		Stream<Integer> stream2 = Stream.generate(()->1);
		// limit is an intermediate operation that sets the maximum number of streams
		// forEach traversal is to terminate the operation
		stream2.limit(5).forEach(x->System.out.println(x) );
		
		// 4 through String.iterate
		// Ditto, infinite flow
		// Parameter 1 is the starting value, parameter 2 is function, with parameters and return values
		// x+2 equals two steps for (int i = 1; true; I + = 2)
		Stream<Integer> stream3 = Stream.iterate(1, x->x+2);
		stream3.limit(10).forEach(x->System.out.println(x));
		
		// 5 API of existing classes
		String string = "abc";
		IntStream chars = string.chars();
		chars.forEach(x->System.out.println(x));
	}
}

Posted by unknown101 on Tue, 02 Nov 2021 15:46:14 -0700