Java8 real study notes (Chapter 1 to 3)

Java8 actual reading notes

Why should we care about the first chapter Java 8

Points

  • Streaming
  • Behavior using parametric methods to pass a code
  • In parallel with the shared data variable
  • External iteration (need to call to a for-each iteration manual)
  • Internal iteration (iteration performed within the library, do not need to manually invoke the for-each)
  • Java 8 Stream API solves the routine when the processing set and obscure , and difficult to use multi-core .
  • Using the default method , the class does not implement method to achieve this is to provide content

The second chapter of the behavioral parameters passed by the code

Outline

  • This chapter introduces the workload due to the constant change brought about, and the use of behavioral parameters of ways to address the needs of demand in this scenario
  • And by the behavior of the parameter with the use of anonymous class code becomes flexible so that in turn lead lambda expression occurs

Key words

  • Predicate : The library defines a class " custom action " of arithmetic functions, these functions receives one argument, and the argument we know the past, it is an object callable, which can be used as a return result value condition, this function is a predicate , in other words, is a function returning a boolean value, as shown in the following code block, this function is an abstract test predicate.
    public interface ApplePredicate{
        boolean test (Apple apple);
    }
  • Parametric behavior allows more actions method takes as a parameter (which is the method defined interfaces act more) as a parameter, and is used internally to perform different behaviors.
  • Anonymous classes using anonymous class is actually for the convenience of the behavioral parameters, in order to achieve a variety of behaviors defined interface is not so complicated, that is not built so much implementation class, when you call, implement the interface directly in the form of an anonymous class and do different behaviors. But by using anonymous classes, the code becomes very long-winded and not so good maintenance and legibility is very poor.
  • the lambda the lambda expression is to optimize the above phenomena.

third chapter

Points

  • lambda Guanzhongkuibao
  • Where and how to use lambda
  • Surround execution mode
  • Interface type inference function
  • Method references
  • lambda complex

    Benevolence

    Can the lambda expression understood as succinctly expressed can deliver the anonymous one way function: it has no name, but it has a list of parameters , the function body , return type , there may be a thrown exception list .
  • Anonymous We say anonymous, because it is not a common method as there is a clear name: write less and think more.
  • Function we say that it is a function, not because the lambda function the same way as belonging to a particular class (My understanding is: you can go directly invoked in other classes), but the methods and the same, there is a list of parameters, and other body functions.
  • Transmitting a lambda expression can be used as a method to pass parameters, or stored in a variable.
  • Simple and do not need to write as many template code like anonymous classes.

Structure
  • Parameter list (), (parameter 1, ...)
  • Arrow ->
  • lambda lambda expression is the body of the return value.
For example
  1. () -> {} The lambda no parameters and returns void
  2. () -> "success" of this lambda no parameters and returns a String as an expression.
  3. () -> {return "success ";} The lambda no parameters and returns String (the explicit return statement)
    above example can be seen, there are two main lambda, one for the expression , one for the explicit return statement , the display returns to the block statement is typically a statement greater than, and surrounded by braces, in fact, within the general procedure code block, and writing the same code block , it is necessary to use braces once written in the normal encoding.

    Where can I use lambda

    Functional Interface

    Interface function is only an abstract method defined interface.

    note:

    If there are many default method (default statement) interface, but as long as the interface defines an abstract way, that this interface is a function interface.

    Use functional interface

    lambda expressions allow you to form within the Union for the abstract methods provide direct functional interface, and the whole expression (in fact, is the way the body's statement) as an example of functional interface .

    Functions descriptor

    Abstract method called function interface descriptor function, an abstract method signature is substantially signature lambda expression.

    Signature example :
  • ()-> void It represents the argument is null, void returns
  • boolean test(Apple apple); This method is abstract functional interface, then it is a signature (Apple apple) -> boolean.

    note:

    Signature lambda expressions and abstract methods need to function as the interface.

    Instructions
public void process(Runnable r){
    r.run();
} 

The method Runable process parameter type, in vivo methods call Runnable.run abstract methods, is summarized, the process method using Runnable.run () method for final operation, the method does not return value, if the return value is Runnable.run () returns the value of the method of treatment. Since the function is a Runnable interface, run method is an abstract method. So call the process method only you need to write something like this:

process(() -> System.out.println("This is awesmoe!!");

From here you can understand what? ? ?

如果方法入参使用了函数式接口作为参数,那么方法体里面如果使用该函数式接口调用相应的抽象方法,那么就可以在调用process方法式,在原本属于函数式接口参数的位置,直接用抽象方法实现即可,这个实现需要以lambda表达式书写,即参数列表、箭头、lambda主体。
所以回头看看函数式接口的定义,只有一个抽象方法的接口,为什么只有一个抽象方法,如果这个runnable接口的抽象方法有多种的话,按照上述的写法还能合理吗?
@FunctionalInterface

If you want to write a function interface, it suggested adding this comment, if you do not meet the specification of the interface functions, the compiler will prompt an error. This comment is not necessary, but there are not very useful, first, prompt yourself, but prompt other programmers.

practice

@FunctionalInterface
public interface UserService {
    void testDemo();
    default String sayHello(FoodService r) {
         return r.sayHello();
    }
}

@FunctionalInterface
public interface FoodService {
    String sayHello();
}

@RunWith(SpringRunner.class)
@SpringBootTest
@WebAppConfiguration
public class LogbackServiceImplTest {

    @Before
    public void setUp() throws Exception {
        System.out.println("测试开始。。。。");
    }

    @After
    public void tearDown() throws Exception {
        System.out.println("测试结束。。。。");
    }
    public String execute(UserService userService, FoodService foodService) {
        userService.testDemo();
        return userService.sayHello(foodService);
    }

    @Test
    public void test() {
        String execute = this.execute(() -> {
            System.out.println("this is my demo!");
        }, () -> {
            return "this is my second demo!";
        });
        System.out.println(execute);
    }
}

It defines two functions interface, UserService, FoodService, which UserService also defines a default method, this test is some validation I had some understanding of functional interface and do.

Java API provides several functions interface

Predicate

Abstract methods : boolean test (T t);
usage scenario : when your process involves a boolean determination condition, and this condition is determined or a dynamic diversity, then you can use this interface, in your approach to the Senate in plus a Predicate type of parameter.
Example :

public <T> List<T> filter(List<T> list,Predicate<T> p){
    List<T> results = new ArrayList<>();
    for(T s : list){
        if(p.test(s)){
            results.add(s);
        }
    }
    return results;
}

The example focus is, for diverse entities s filter condition, if there is this kind of scenario, only the behavior of a variety of abstraction, and the functional interface definition parameters which can be put into, so the above examples of call as follows:

@Test
public void test() {
    List<String> strings = Arrays.asList("1", "2", "", "3", "4");
    List<String> list = this.filter(strings, (String s) -> !s.isEmpty());
    System.out.println(list.toString());
}
note:
其实从调用来看只需关注函数式接口具体实现那一部分,所以上述的filter方法内部也可以做一些环绕执行的方式。Predicate函数式接口没有指定类型,用的是泛型,所以在编写lambda表达式时,参数列表需要指定类型,如果有的函数式接口已经指定类型,那么(String s)中的String可以忽略,直接一个s -> !s.isEmpty()即可。
Consumer

Abstract methods : void accept (T t);
usage scenarios : For diverse behavior if no return value, the function can use interface.
Example :

public <T> void forEach(List<T> list, Consumer<T> c){
    for(T i: list){
        c.accept(i);
    }
}

调用:
@Test
public void test() {
    List<Integer> integers = Arrays.asList(1, 2, 3, 4);
    this.forEach(integers, (Integer i) -> System.out.println(i));
}
Function

Abstract methods : R apply (T t);
usage scenario : If you enter a reference method is one type, another type of return value, the function interface fully meet your needs.
Example :

public <T,R> List<R> map(List<T> list, Function<T,R> f){
    List<R> result = new ArrayList<>();
    for(T s : list){
        result.add(f.apply(s));
    }
    return result;
}

调用:
@Test
public void test() {
    List<String> strings = Arrays.asList("lambdas", "in", "action");
    List<Integer> list = this.map(strings, (String s) -> s.length());
    System.out.println(list.toString());
}
Supplier

Abstract methods : T get ();

Usage scenarios : If you are a method of the reference is empty, another type of the return value, the function interface may be used

Example :

Generally is used to create a new entity Supplier, such as Student :: new, there is a return Supplier , Note that if there is no no-argument constructor in Student will give an error. Student consistent because no-argument constructor and Supplier's signature, the parameters are empty and returns an entity.

BiFunction

Abstract methods : R apply (T t, U u);

Usage scenarios : the two types of parameters, the third type of return value.

Example :

slightly

上述五个函数式接口应该涵盖了我们平时用到方法类型,返回布尔值、返空回值、返回指定类型等方法,所以说很有用。

Primitive type specialization

Java type or use a reference type (such as Byte, Integer, Object, List), either a primitive type (such as byte, double, int, char). But generics can be bound to a reference type. This is due to the generic internal implementation. Thus it involves two operations:

  • Packing a raw type to the type of mechanism corresponding references in Java, this mechanism becomes packing.
  • Unpacking reference type is converted to the corresponding original type called unpacking.

Examples

List<Integer> list = new ArrayList<>();
for(int i = 300;i<400;i++){
    list.add(i);
}

i put into the list of the packing operation involves, after the value of packing essentially wrap the original type, and stored in a heap . Therefore, the value of the packing requires more memory and requires additional memory search to obtain the original value wrapped.
Java 8 brings a special version we said earlier function interface, in order to avoid automatic packing operation when the input and output are primitive types.

Functional Interface Functions descriptor Similar to the original type specialization
Predicate T -> boolean IntPredicate、LongPredicate、DoublePredicate
Consumer T -> void IntConsumer、LongConsumer、DoubleConsumer
Funcation<T,R> T -> R IntFunction (The parameter is int, return value R type)
IntToDoubleFunction (the parameter of type int and returns a value of type double)
IntToLongFunction (parameter into an int, long type return value)
lung Function (The parameter type long return value R type)
LongToDoubleFunction (the parameter type long double type return value)
LongToIntFunction (the parameter type long int type of return value)
DoubleFunction (The parameter type double, the return value of type R)
ToIntFunction (T is a reference type of the return value of type int)
ToDoubleFunction (T into the reference type as the return value of type double)
ToLongFunction (T is a reference type of the return value of type long)
Supplier () -> T BooleanSupplier,IntSupplier,LongSupplier,DoubleSupplier
UnaryOperator T -> T IntUnaryOperator, LongUnaryOperator, DoubleUnaryOperator
BinaryOperator (T,T) -> T IntbinaryOperator,LongBinaryOperator,DoubleBinaryOperator
BiPredicate<L,R> <L,R> -> boolean
BiConsumer<T,U (T,U) -> void
BiFunction<T,U,R> (T,U) -> R ToIntBiFunction<T,U>
ToLongBiFunction<T,U>
ToDoubleBiFunction<T,U>

Any function interface subjects are not allowed to throw an exception.

Type checking, type inference and restrictions

Type checking

Type of the lambda expression is inferred from the context of lambda.

  • Context is added in a lambda expression parameter in the method, then the type of the lambda expression can be specified when defining multiple methods by which to determine the function interface (interface function for the expression of the target type ), or a variable receiving a lambda expression, the expression is determined by the type of the variable.

Check order

  • First you need to find the method is declared.
  • A second step of determining the position of the writing lambda expression parameters on the process
  • The third step is to confirm whether the parameter is declared as a function of the position of interface
  • A fourth step of determining an abstract method (function descriptor) The function of the interface, accepts what a value of the value (or empty), a return.
  • Writing a fifth step, the actual parameters of the process, i.e., the interface function declared parameters must conform to the interface function is defined.

These are the order of examination, there is an assignment context , method invocation context , casts the context of these three ways to obtain the target type.

Use local variables
**自由局部变量**:不是函数式接口抽象方法参数,而是在外层作用域中定义的变量,它们被称为 **捕获lambda**,lambda没有限制捕获实例变量(我认为是在lambda表达式内创建的新的实例,而不是一个可变的引用)和静态变量。但是局部变量必须显示声明为final或事实上是final。原因如下:
  • Instance variables are stored in stack, local variables are stored on the stack.
  • Equivalent access when accessing free copy of local variables, rather than a true original variables
  • If lambda is the use of a thread, the thread assigned another free variable this variable will recover, this time to go visit this free lambda variable will be problems, that is not thread safe .

So if the free variable does not change once they are assigned after so it can guarantee true copy of the original variables and the same.
Other features:

  • Local variables are stored on the stack, implicitly indicating that they are limited to the thread where the years, while the heap is multithreaded access (multi-threaded shared).

Closure : is a function instance (is an object that can be invoked, it saves the scope of information that created it), and it can have unlimited access to non-local variables of the function. Java does not support explicit closures, generally through non-static inner class support.

Guess you like

Origin www.cnblogs.com/bibibao/p/11427221.html