当前位置:网站首页>Lambda, functional interface, stream

Lambda, functional interface, stream

2020-11-13 08:21:03 Xiao Pengwei

Statement : This article is from 《 Master Lambda expression :Java Multicore programming 》, And other network resources , if there be , The reference link will be attached to the end of , Without permission , Do not reprint , If there is a mistake , Please give me some advice .

problem 1: Why use lambda?

(1)Lambda Allows you to take a function as an argument to a method
(2)Lambda Expression can make the code more concise and compact

problem 2:Lambda What are the characteristics ?
  • Optional type declaration : Parameter types do not need to be declared , Compiler can identify parameter values uniformly .
  • Optional parameter parentheses : A parameter does not need to define parentheses , But multiple parameters need to define parentheses .
  • Optional braces : If the body contains a statement , You don't need braces .
  • Optional return key : If the body has only one expression return value, the compiler returns the value automatically , Braces need to specify that the expression returns a value .

Lambda It can be seen as an anonymous way to you , Have a more concise Syntax , You can omit the modifier , Return type ,throws sentence , In some cases, you can omit the parameter type .

problem 3:Lambda grammar ?

grammar : Include a list of parameters and Lambda body , Intermediate use -> Division

//  Single parameter 、 When operating 
parameter -> expression  or 
//  multi-parameter 、 More operation 
(parameter1, parameter2) ->{
     
	statements; 
}

example :

//  expression 、 No parameter 
() -> System.out.println("hello xpwi");

//  Receive a parameter ( Numeric type ), Back to its 2 Times value   
x -> 2 * x  
  
//  Accept 2 Parameters ( Numbers ), And return their difference   
(x, y) -> x – y  
  
//  receive 2 individual int Type integer , Back to their and   
(int x, int y) -> x + y  
  
//  Accept one  string  object , And print on the console , No value returned ( Looks like a return void)  
(String s) -> {
    
	System.out.print(s);
	System.out.print(s + "=S");
}

This is it. Lambda expression , But there will be questions ,What???

problem 4: How to use this expression ? As a parameter ? What is the return value ?

Its return value is an interface , We can write this way :

//  perform 
@Test
public void test() {
    
    runnable.run();
}
//  Definition 
Runnable runnable = () -> {
    
	System.out.println("hello");
	System.out.println("xpwi");
};

This may be thought of in multithreading Runnable Interface creation mode , There is no multithreading meaning here , Just use an interface , Use its name meaning , There's a run() Method , Said to start ,running...

problem 5: So is the interface any interface ? Can you define it yourself ?

The interface can be a custom interface , But the interface should conform to the functional interface specification

problem 6: What is a functional interface ?

(1) There is only one abstract method , There can be other non abstract methods .

(2) Can pass Lambda Expression to create the object of the interface .

(3) It can be used on the interface @FunctionalInterface annotation , At compile time, check if it is a functional interface

problem 7: How to define interface ?

Custom interface :

//  It's not usually used like that , No need to customize , This is used to illustrate 
@FunctionalInterface
public interface MyNoticeInterface {
    
    public abstract Boolean doNotice(String user);

    default String dotice(String user) {
    
        return "null";
    }
}

Use of interfaces :

@Test
public void test() {
    
    Boolean xpwi = noticeInterface.doNotice("xiaopengwei");
    System.out.println(xpwi);
}

private MyNoticeInterface noticeInterface = (user) -> {
    
    System.out.println("hello");
    System.out.println(user);
    return true;
};
problem 8: Don't want to define interfaces yourself , What do I do ???

JDK 1.8 Previous functional interfaces :

  • java.lang.Runnable
  • java.util.concurrent.Callable
  • java.security.PrivilegedAction
  • java.util.Comparator
  • java.io.FileFilter
  • java.nio.file.PathMatcher
  • java.lang.reflect.InvocationHandler
  • java.beans.PropertyChangeListener
  • java.awt.event.ActionListener
  • javax.swing.event.ChangeListener

JDK 1.8 New function interface : stay java.util.function It's a bag :
You can also see it in the rookie tutorial : Novice tutorial -JAVA8 Functional interface

problem 9: Common functional interface
Serial number Functional interface Abstract method describe
1 BiConsumer<T,U> void accept(T t, U u); Represents an operation that accepts two input parameters , And it doesn't return any results ; other :andThen()
2 BiFunction<T,U,R> R apply(T t, U u); Represents a method that accepts two input parameters , And returns a result
3 BinaryOperator R apply(T t, U u); Represents an operation on two operators of the same type , And returns a result of the same type of operator ; Inherited from :BiFunction
4 BiPredicate<T,U> boolean test(T t, U u); Represents a two-parameter boolean Value method
5 BooleanSupplier boolean getAsBoolean(); On behalf of boolean The provider of the value result
6 Consumer void accept(T t); Represents an operation that accepts an input parameter and returns nothing
7 DoubleBinaryOperator double applyAsDouble(double left, double right); That represents the action on two double The operation of a value operator , And it returns one double The result of the value .
8 DoubleConsumer void accept(double value); Represent an acceptance double Operation of a value parameter , And does not return a result .
9 DoubleFunction R apply(double value); To accept a double Value the method of the parameter , And return the result
10 DoublePredicate boolean test(double value); Represents a possession double Value of parameter boolean Value method
11 DoubleSupplier double getAsDouble(); Representing one double The provider of the value structure
12 DoubleToIntFunction int applyAsInt(double value); Accept one double Type of input , Return to one int Type the results .
13 DoubleToLongFunction long applyAsLong(double value); Accept one double Type of input , Return to one long Type the results
14 DoubleUnaryOperator double applyAsDouble(double operand); Accept a parameter of the same type double, The return value type is also double .
15 Function<T,R> R apply(T t); Accept an input parameter , Return a result .
16 IntBinaryOperator int applyAsInt(int left, int right); Accept two arguments of the same type int, The return value type is also int .
17 IntConsumer void accept(int value); Accept one int Type input parameter , No return value .
18 IntFunction R apply(int value); Accept one int Type input parameter , Return a result .
19 IntPredicate boolean test(int value); Accept one int Input parameters , Returns the result of a Boolean value .
20 IntSupplier int getAsInt(); No parameter , Return to one int Type the results .
21 IntToDoubleFunction double applyAsDouble(int value); Accept one int Type of input , Return to one double Type the results .
22 IntToLongFunction long applyAsLong(int value); Accept one int Type of input , Return to one long Type the results .
23 IntUnaryOperator int applyAsInt(int operand); Accept a parameter of the same type int, The return value type is also int .
24 LongBinaryOperator long applyAsLong(long left, long right); Accept two arguments of the same type long, The return value type is also long.
25 LongConsumer void accept(long value); Accept one long Type input parameter , No return value .
26 LongFunction R apply(long value); Accept one long Type input parameter , Return a result .
27 LongPredicate boolean test(long value); R Accept one long Input parameters , Returns the result of a Boolean value type .
28 LongSupplier long getAsLong(); No parameter , Return a result long Type value .
29 LongToDoubleFunction double applyAsDouble(long value); Accept one long Type of input , Return to one double Type the results .
30 LongToIntFunction int applyAsInt(long value); Accept one long Type of input , Return to one int Type the results .
31 LongUnaryOperator long applyAsLong(long operand); Accept a parameter of the same type long, The return value type is also long.
32 ObjDoubleConsumer void accept(T t, double value); Accept one object Type and a double Type input parameter , No return value .
33 ObjIntConsumer void accept(T t, int value); Accept one object Type and a int Type input parameter , No return value .
34 ObjLongConsumer void accept(T t, long value); Accept one object Type and a long Type input parameter , No return value .
35 Predicate boolean test(T t); Accept an input parameter , Returns a Boolean result .
36 Supplier T get(); No parameter , Return a result .
37 ToDoubleBiFunction<T,U> double applyAsDouble(T t, U u); Accept two input parameters , Return to one double Type the results
38 ToDoubleFunction double applyAsDouble(T value); Accept an input parameter , Return to one double Type the results
39 ToIntBiFunction<T,U> int applyAsInt(T t, U u); Accept two input parameters , Return to one int Type the results .
40 ToIntFunction int applyAsInt(T value); Accept an input parameter , Return to one int Type the results .
41 ToLongBiFunction<T,U> long applyAsLong(T t, U u); Accept two input parameters , Return to one long Type the results .
42 ToLongFunction long applyAsLong(T value); Accept an input parameter , Return to one long Type the results .
43 UnaryOperator R apply(T t); Accept a parameter of type T, The return value type is also T; Inherited from :Function.
problem 10: Write a functional interface instance ?
@Slf4j
public class LambdaTest {
    

    @Test
    public void test() {
    
        String user = "xiaopengwei";
        Integer age = 18;
        noticeHandler.accept(user);
        noticeWithAgeHandler.accept(user, age);
    }

    private Consumer<String> noticeHandler = (String user) -> {
    
        log.info(" notice : " + user);
    };

    private BiConsumer<String, Integer> noticeWithAgeHandler = (user, age) -> {
    
        log.info(" notice : user=" + user + ", age=" + age);
    };

}

image BiConsumer Generics after , Compile time , It can also be inferred from context without writing , But I think it's all about writing .

problem 11:andThen() How do you use it? ?

For the same parameters , Perform multiple operations , You can use it directly andThen(), Simplify writing :

// andThen
@Slf4j
public class LambdaTest {
    
    @Test
    public void test() {
    
        String user = "xiaopengwei";
        noticeHandler.andThen(thenNoticeHandler).accept(user);
    }

    private Consumer<String> noticeHandler = (String user) -> {
    
        log.info(" notice : " + user);
    };

    private Consumer<String> thenNoticeHandler= (user) -> {
    
        log.info("after andThen  notice : user=" + user);
    };

}

Of course , You can hang back all the time ,,

@Slf4j
public class LambdaTest {
    
    @Test
    public void test() {
    
        String user = "xiaopengwei";
        noticeHandler.andThen(thenNoticeHandler).andThen(thenThenNoticeHandler).accept(user);
    }

    private Consumer<String> noticeHandler = (String user) -> {
    
        log.info(" notice : " + user);
    };

    private Consumer<String> thenNoticeHandler = (user) -> {
    
        log.info("after andThen  notice : user=" + user);
    };

    private Consumer<String> thenThenNoticeHandler = (user) -> {
    
        log.info("after andThen Then  notice : user=" + user);
    };
}
problem 12: Okay ,Stream Well ??

Stream Introduction to , see : Novice tutorial -Java 8 Stream

Let programmers write efficiently 、 clean 、 Simple code .

Lazy evaluation , Flow in the middle of the process , It's just a record of the operation , Not immediately executed , It takes until the termination operation is performed before the actual calculation is performed .

Java 8 stream Detailed usage

This article has a comparative introduction , Here is the main category :

There are such classifications in the article :
 Insert picture description here

  • No state : The processing of an element is not affected by the previous element ;
  • A stateful : The operation cannot continue until all elements have been obtained .
  • Non short circuit operation : All elements must be processed to get the final result ;
  • Short circuit operation : When you meet some elements that meet the conditions, you can get the final result , Such as A || B, as long as A by true, There is no need to judge B Result .

(1) Create the scene of the flow

list.stream(); //  Streaming 
list.parallelStream(); //  Parallel flow 

//  Array stream 
Integer[] nums = new Integer[10];
Stream<Integer> stream = Arrays.stream(nums);

//  Use Stream Static methods in :of()、iterate()、generate()  establish 
Stream<Integer> stream = Stream.of(1,2,3,4,5,6);
 
Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 2).limit(6);
stream2.forEach(System.out::println); // 0 2 4 6 8 10
 
Stream<Double> stream3 = Stream.generate(Math::random).limit(2);
stream3.forEach(System.out::println);

//  Use  BufferedReader.lines()  Method , Turn each line into a stream 
BufferedReader reader = new BufferedReader(new FileReader("F:\\test_stream.txt"));
Stream<String> lineStream = reader.lines();
lineStream.forEach(System.out::println);

//  Use  Pattern.splitAsStream()  Method , Separate strings into streams 
Pattern pattern = Pattern.compile(",");
Stream<String> stringStream = pattern.splitAsStream("a,b,c,d");
stringStream.forEach(System.out::println);

(2) Middle operation of flow

1、 Screening and slicing

operation describe
filter Filter some elements in the stream
limit(n) obtain n Elements
skip(n) skip n Elements , coordination limit(n) Paging possible
distinct Through the elements in the stream hashCode() and equals() Remove duplicate elements

2、 mapping

operation describe
map Receive a function as an argument , This function is applied to each element , And map it to a new element .
flatMap Receive a function as an argument , Replace each value in the stream with another stream , Then connect all streams into one stream .

3、 Sort

operation describe
sorted() Natural ordering , Elements in the stream need to implement Comparable Interface
sorted(Comparator com) Custom sort , Customize Comparator collator

4、 consumption

operation describe
peek As in map, You can get every element in the stream . but map It received a Function expression , There is a return value ; and peek Receive is Consumer expression , no return value .

Termination of stream

1、 matching 、 Aggregation operation

operation describe
allMatch Receive one Predicate function , When every element in the stream matches the assertion true, Otherwise return to false
noneMatch Receive one Predicate function , When every element in the stream does not match the assertion true, Otherwise return to false
anyMatch Receive one Predicate function , As long as one element in the stream satisfies the assertion, it returns true, Otherwise return to false
findFirst Returns the first element in the stream
findAny Returns any element in the stream
count Returns the total number of elements in the stream
max Returns the maximum value of the element in the stream
min Returns the minimum value of the element in the stream

2、 Protocol operation

Optional reduce(BinaryOperator accumulator): On first execution ,accumulator The first parameter of the function is the first element in the stream , The second parameter is the second element of the element in the stream ; On second execution , The first parameter is the result of the first function execution , The second parameter is the third element in the stream ; By analogy .

T reduce(T identity, BinaryOperator accumulator): The process is the same as above , It's just the first time it's executed ,accumulator The first argument to the function is identity, The second parameter is the first element in the stream .

<U> U reduce(U identity,BiFunction<U, ? super T, U> accumulator,BinaryOperator <U> combiner): In serial stream (stream) in , This method is the same as the second one , That's the third parameter combiner It won't work . In parallel streams (parallelStream) in , We know that the stream is fork join Multiple threads are executed , At this point, the execution process of each thread follows the second method reduce(identity,accumulator) equally , And the third parameter combiner function , The execution result of each thread is regarded as a new stream , And then use the first method reduce(accumulator) Process specification .

3、 Collection operation

operation describe
collect Receive one Collector example , Integrate the elements in the flow into another data structure .
problem 13:Stream Common instance code ?

More common treatment , It's repetitive and boring , But you have to

Code example :

//  More common scenarios 
@Slf4j
public class StreamTest {
    

    @Test
    public void test() {
    
        List<UserDTO> userDTOS = userBOSupplier.get();
        AtomicInteger begin = new AtomicInteger(1);
        List<UserBO> userBOs = userDTOS.stream().filter(bo -> bo.getEyesColor().equals("red"))
                .sorted((Comparator.comparingInt(UserDTO::getUserAge)))
                .map(dto -> {
    
                    UserBO userBO = new UserBO(dto.getUserName(), dto.getUserAge(), begin.getAndIncrement());
                    return userBO;
                }).collect(Collectors.toList());

        log.info(" Sorted by age ,  Red eyed ,  user " + JSONObject.toJSONString(userBOs));
    }

    private Supplier<List<UserDTO>> userBOSupplier = () -> {
    
        UserDTO user1 = new UserDTO("John", 31, "blue");
        UserDTO user2 = new UserDTO("Bob", 34, "red");
        UserDTO user3 = new UserDTO("Lucy", 32, "red");
        UserDTO user4 = new UserDTO("Tom", 33, "black");
        return new ArrayList<>(Arrays.asList(user1, user2, user3, user4));
    };
}

user BO object :

@Data
@AllArgsConstructor
public class UserBO {
    
    private String userName;
    private Integer userAge;
    private Integer sort;
}

user DTO Entity :

@Data
@AllArgsConstructor
public class UserDTO {
    
    private String userName;
    private Integer userAge;
    private String eyesColor;
}
problem 14:GET

Say it in secret , My public number ID:javajobs

Reference link

(1) Novice tutorial https://www.runoob.com/java/java8-lambda-expressions.html
(2) You know https://www.zhihu.com/question/20125256
(3)https://blog.csdn.net/y_k_y/article/details/84632889

版权声明
本文为[Xiao Pengwei]所创,转载请带上原文链接,感谢

随机推荐