Java 8 simple to use, Android Engineer Interview Questions and answers

         Log.d("I","exe");
    }
}); 
```

> Anonymous Inner Class /The disadvantage of listener interface is that the code is very bloated,and lambda The expression is to simplify it.

```
func(()->Log.d("I","exe")); 
```

> Lambda Expressions don't allow you to perform functions that you couldn't do before

2. Several styles of lambda expressions

  1. Overall style: (parameter list) - > {code block; return **;}```
    (parameter list) - > single line code

    (parameter list) - > {code;}

    (parameter list) - >{
    code;
    Return return value;
    }

    (parameter list) - > {return return value;}

    (parameter list) - > return value

3. Where can lambda expressions be used: on functional interfaces

  1. What is a functional interface: a functional interface is an interface with only one abstract method

    • Note that only the number of abstract methods is limited
    • Even if an interface contains many default / default methods, only one abstract method is defined in the interface, which is still a functional interface
    • Although DefaultInterface has many default methods, it only contains one abstract method, which is also a functional interface
    @FunctionalInterface
    public interface DefaultInterface {
        void f1();
        default void f2(){};
        default void f3(){};
        default void f4(){};
    } 
    
    • For functional interfaces, it is recommended to add the annotation @ functional interface, but it is not necessary
  2. Lambda expression allows the implementation of abstract methods of functional interface directly in the form of inline, and takes the whole lambda expression as an instance of the functional interface

    • It can be seen that passing the specified interface instance and using the anonymous inner class is essentially the same as using the Lambda expression. Both pass an "instance"
    • Lambda expressions just make the code more concise
  3. The signature of abstract methods of functional interfaces is basically the signature of Lambda expressions

    • According to this rule, the corresponding Lambda expression can be written by comparing the 'method form' of the functional interface
    • (type P1, type P2, * * *) - > {method body;}
    @FunctionalInterface
    public interface FuncI1{
        void f();
    }
    @FunctionalInterface
    public interface FuncI2{
        void f1(int p1,int p2);
    }
    
    private void testLambdaFuncSign() {
        //Take Runnable as an example
        //Runnable is a functional interface
        //@FunctionalInterface
        //public interface Runnable {
        Runnable r1 = new Runnable() {
            @Override
            public void run() {
            }
        };
        Runnable r2 = () -> {
        };
    
        //Take the custom functional interface as an example
        FuncI1 funcI11 = new FuncI1() {
            @Override
            public void f() {
            }
        };
        FuncI1 funcI12 = () -> {};
        FuncI2 funcI21 = new FuncI2() {
            @Override
            public void f1(int p1, int p2) {
            }
        };
        FuncI2 funcI22 = (p1, p2) -> {};
    } 
    

4. New functional interface in Java 8

  1. Predicate

    • Predict receives the generic t instance and returns the boolean value. T - > boolean
    • Predict is often used to filter the data in the stream and other scenarios that return a boolean based on one instance
    • Example
    @FunctionalInterface
    public interface Predicate<T> {
        boolean test(T t);
    }
    
    public class Person{
        public String name = "Li Lei";
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }
    @RequiresApi(api = Build.VERSION_CODES.N)
    public boolean testPerson(Person person, Predicate<Person> predicate){
        return predicate.test(person);
    }
    @RequiresApi(api = Build.VERSION_CODES.N)
    public void testPredicate(){
        Predicate<Person> personPredicate = person -> person.getName().equals("Han Meimei");
        testPerson(new Person(),personPredicate);
    } 
    
  2. Consumer

    • The Consumer receives a generic t instance and returns no. T - > void
    • From the naming, it can be seen that only one instance is consumed
    • Example
    @FunctionalInterface
    public interface Consumer<T> {
        //Simply consume 1 instance
        void accept(T t);
    }
    
    @RequiresApi(api = Build.VERSION_CODES.N)
    public void testConsumer(){
        List<String> list = Arrays.asList("1","2","3");
        Consumer<String> consumer = s -> Log.d("TestConsumer","Current item:" + s);
        list.forEach(consumer);
    } 
    
  3. Function

    • Function receives 1 generic t instance and returns 1 generic r instance. T - > R
    • It can be understood as conventional input - > output
    • Example
    @FunctionalInterface
    public interface Function<T, R> {
        //Receive T instance and return R instance
        R apply(T t);
    }
    
    @RequiresApi(api = Build.VERSION_CODES.N)
    public void testFunction(){
        /*
        Function<String, Integer> function = new Function<String, Integer>() {
            @Override
            public Integer apply(String s) {
                return Integer.parseInt(s);
            }
        };
        */
        //Here again, let's review the use of Lambda expressions to represent functional interface instances
        Function<String, Integer> function = s -> Integer.parseInt(s);
        int result = function.apply("1000");
    } 
    
  4. Supplier

    • The Supplier does not receive instances, but directly generates a generic T instance. Void - > T
    • As can be seen from the name, it is a producer
    • Example
    @FunctionalInterface
    public interface Supplier<T> {
        T get();
    }
    @RequiresApi(api = Build.VERSION_CODES.N)
    public void testSupplier() {
        Supplier<Person> supplier = () -> new Person();
        Person person = supplier.get();
    } 
    

5. Method reference

  1. Method references let you create Lambda expressions based on existing methods

  2. Format of method reference: target reference:: method name

  3. There are three main types of method references

    • Method reference to static method
      • Expression: className::func
    • A method reference to a specified method of any class instance
      • Expression: className::func
    • A method reference to the specified method of an existing instance
      • Expression: instance::func
    public class PersonOpt{
        private String gainTag(Person person){
            return "Tag" + person.getName();
        }
    }
    @RequiresApi(api = Build.VERSION_CODES.N)
    public void testMethodReference() {
        //Method reference to static method
        //This points to the static method of the Integer class
        //Essence: className.func(param)
        //Form: className::func
        Function<String,Integer> f1 = (s) -> Integer.parseInt(s);
        Function<String,Integer> f2 = Integer::parseInt;
    
        //A method reference to a specified method of any class instance
        //This refers to the non static method getName in the Person class
        //Essence: param.func()
        //Form: className::func
        Function<Person,String> f3 = (p) -> p.getName();
        Function<Person,String> f4 = Person::getName;
    
        //A method reference to the specified method of an existing instance
        //This refers to the non static method personopt of the personopt instance
        //Essence: instance.func(param)
        //Form: instance::func
        PersonOpt personOpt = new PersonOpt();
        Function<Person,String> f5 = new Function<Person, String>() {
            @Override
            public String apply(Person person) {
                return personOpt.gainTag(person);
            }
        };
        Function<Person,String> f6 = personOpt::gainTag;
    } 
    
  4. Reference to constructor: ClassName::new

    • Constructor references are suitable for producers / suppliers
    • The form of constructor is void - > t
    @RequiresApi(api = Build.VERSION_CODES.N)
    public void testConstructorRef(){
        Supplier<Person> supplier1 = new Supplier<Person>() {
            @Override
            public Person get() {
                return new Person();
            }
        };
        Supplier<Person> supplier2 = () -> new Person();
        //The form of public Person() {} constructor is void - > t
        Supplier<Person> supplier3 = Person::new;
    } 
    
  5. How to use Lambda expressions and method references

    Here, take a custom requirement as an example

    Many of the methods we use are passed in parameters and the results are returned

    For example, enter three parameters and return one result

    There are many methods in the same form:

    public String f1(int p1,long p2, double p3){
        return **;
    }
    public int f2(int p1,String p2,Person p3){
        return **;
    }
    public Person f3(int p1,long p2,Dog dog){
        return **;
    } 
    

    Using lambda expressions and function references, formal reuse can be realized and the amount of code can be reduced

    • First, create a corresponding functional interface according to the form of input parameters and return results. For example, if three input parameters return one result, you can define a functional interface containing four generic data
    • Then use Lambda expression to create the corresponding instance of the functional interface. Avoid declaring too many methods
    //1: Construct a functional interface / an interface with only one abstract method
    @FunctionalInterface
    public interface CustomInterface<Source,Param1,Param2,Result>{
        Result gainResult(Source source,Param1 param1,Param2 param2);
    }
    //2: Create an instance of the functional interface
    public void testCustomInterface(){
        //Original form creation
        CustomInterface<String,Integer,Integer,String> c1 = new CustomInterface<String, Integer, Integer, String>() {
            @Override
            public String gainResult(String s, Integer param1, Integer param2) {
                return s.substring(param1,param2);
            }
        };
        //lambda expression creation
        //(parameter list) - > {return result;}
        CustomInterface<String,Integer,Integer,String> c2 = (source,param1,param2) -> {return source.substring(param1,param2);};
        //(parameter list) - > result
        CustomInterface<String,Integer,Integer,String> c3 = (source,param1,param2) -> source.substring(param1,param2);
        //Direct use method reference
        //className::func
    

Design pattern learning notes

Design pattern series learning video

CodeChina open source project: Android learning notes summary + mobile architecture Video + big factory interview real questions + project actual combat source code

ram2) -> source.substring(param1,param2);
//Direct use method reference
//className::func

Design pattern learning notes

[external chain picture transferring... (img-7Jt4nQAl-1630931419562)]

Design pattern series learning video

[external chain picture transferring... (img-U8D53lRV-1630931419564)]

CodeChina open source project: Android learning notes summary + mobile architecture Video + big factory interview real questions + project actual combat source code

Tags: Java Android Design Pattern

Posted on Mon, 06 Sep 2021 17:44:56 -0400 by robman2100