New features of jdk (1) interface and lambda expression

introduction

  • With the continuous development of programming technology, Oracle has made many upgrades to Java in order to facilitate programming and improve the maintainability of the project, such as the introduction of new lambda expressions, the addition of static methods and default methods and extraction in interfaces Private methods, let's review lambda expressions first.

lambda expression

Why use lambda expressions?

  • Lambda expressions are to make interface programming more convenient. This can also be considered from the programming ideas of lambda expressions. Functional thinking tries to ignore the object-oriented complex syntax: "emphasize what to do, not what form to do" , So this can make java programming more elegant and the code more concise.

What are the matters needing attention when using Lambda expressions?

  1. The use of Lambda must have an interface, and requires only one abstract method in the interface.
  2. There must be a context to derive the interface corresponding to Lambda.
    The following is a concrete example understanding of lambda expressions.
    According to the assignment of local variables, we know the interface corresponding to Lambda
    Runnable r = () -> System.out.println("Lambda expression");
    According to the parameters of the calling method, we know the interface corresponding to Lambda
    new Thread(() -> System .out.println("Lambda expression")).start();
    lambda expression can be understood as an object that implements an interface ()

What is the difference between lambda expressions and anonymous inner classes?

1) The required type is different.
Anonymous inner class: it can be an interface, an abstract class, or a concrete class.
Lambda expression: only an interface.

2) Use restrictions are different.
If there is only one abstract method in the interface, you can Using Lambda expressions, you can also use anonymous inner classes. If there is more than one abstract method in the interface, you can only use anonymous inner classes instead of Lambda expressions.
3) Different implementation principles.
Anonymous internal classes: After compilation, a separate .class bytecode file is generated.
Lambda expression: After compilation, there is no separate .class bytecode file. The corresponding bytecode will be dynamically generated at runtime.

Case

Use lambda expressions and anonymous inner classes to implement a continuous interface, and experience the difference between the two methods.
Interface class 1

public interface Addable {
    int add(int x, int y);
}

Interface class 2

public interface Eatable {
    void eatable(String s);
}

Interface class 3

public interface Likable {
    void like(String s);
}

Test class

public class LambdaDemo {
    public static void main(String[] args) {

        useAddable(new Addable() {
            @Override
            public int add(int x, int y) {
                System.out.println("------------Add采用匿名内部类-------------");
                return x+y;
            }
        });

        useEatable(new Eatable() {
            @Override
            public void eatable(String s) {
                System.out.println("----------Eat采用匿名内部类------------");
                System.out.println(s);
            }
        });

        useLikable(new Likable() {
            @Override
            public void like(String s) {
                System.out.println(s);
            }
        });

        System.out.println("----------采用lambda表达式--------------");

        useAddable((int x,int y)->{
            System.out.println("-------------Eat采用lambda表达式---------------");
            return x+y;
        });

        useEatable((String str)->{
            System.out.println("----------Eat采用lambda表达式------------");
        });
        useLikable((String s)->{
            System.out.println(s);
        });

        System.out.println("----------采用省略lambda表达式----------");
        useEatable((s)-> System.out.println(s));

        useAddable((x,y)->x+y);

        useLikable((s)-> System.out.println(s));
    }

    public static void useEatable(Eatable eat){
        eat.eatable("我爱吃苹果");
    }

    public static void useAddable(Addable add){
        int sum = add.add(10, 20);
        System.out.println("sum:"+sum);
    }

    public static void useLikable(Likable like){

        //System.out.println("--------i love java---------");
        //System.out.println("---------i love python----------");
        like.like("--------i love java---------");
        like.like("---------i love python----------");
    }

}

Test Results
Insert picture description here

New interface features

  • Jdk can add static methods, default methods, private methods, etc. to the interface according to user needs. This is to facilitate project expansion and reduce the coupling between codes. Let's look at the actual case.

Case

Experience the new private method with method body in jdk.
Interface class

public interface MyInterface {

    void show(String s);

    public static void show01(){
        System.out.println("---------this is static void show01----------");
        show03();
        //无法调用非静态方法
        //show04();
    }

    public default void show02(){
        System.out.println("-----------this is default void show03------------");
        show03();
        show04();
    }

    private static void show03(){
        System.out.println("---------this is private static void show03--------");
    }

    private void show04(){
        System.out.println("---------this is private normal void show04--------");
    }
}

Test class

public class TestDemo {
    public static void main(String[] args) {
        useMyInterface((s)->{
            System.out.println("------这是通过lambda表达式实现MyInterface的show方法-------");
            System.out.println(s);
        });
        MyInterface.show01();


        MyInterface myInterface = new MyInterface() {
            @Override
            public void show(String s) {
                System.out.println("------这是通过new的对象实现MyInterface的show方法-------");
                System.out.println(s);
            }
        };
        myInterface.show("I LOVE PYTHON");
        myInterface.show02();
    }

    public static void useMyInterface(MyInterface myInterface){
        myInterface.show("i love java");
    }
}

Test Results
Insert picture description here

notes

Default methods can call private static methods and non-static methods.
Static methods can only call private static methods.

Method reference

Why are there method references?

When using Lambda expressions, the code we actually pass in is a solution: take parameters to operate, then consider a situation: if we specify the operation scheme in Lambda, the same scheme already exists somewhere, so There is no need to write repetitive logic anymore.

What is a method reference character?

:: This symbol is a reference operator, and the expression it is in is called a method reference

What is the relationship between lambda expressions and method references?

Method reference is the twin brother of
Lambda. If you use Lambda, then according to the principle of "derivable is omissible", no need to specify the parameter type, and no need to specify the overload form, they will all be deduced automatically; if you use method reference, the same is true It can be deduced according to the context.

Case number one

Various interfaces

public interface Converter {
    int convert(String s);
}
public interface MyString {
    String mySubString(String str,int x, int y);
}

public interface Printable {
    void printUpperCase(String s);
}

    Student build(String name,int age);
}

Student class

public class Student {
    private String name;
    private int age;
    public Student() {
    }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

printStr class

public class PrintStr {
    public void printUpper(String s){
        String str = s.toUpperCase();
        System.out.println(str);
    }
}

Test class

public class ReferenceDemo {
    public static void main(String[] args) {
       useConverter((s)->{
            int i = Integer.parseInt(s);
            //System.out.println(i);
            return i;
        });
        //采用静态方法
        useConverter(Integer::parseInt);
        System.out.println("-----------------------");
        //采用lambda接口来
        usePrintStr((s)->{
            System.out.println(s.toUpperCase());
        });
        //采用对象应用方法
        PrintStr printStr = new PrintStr();
        usePrintStr(printStr::printUpper);
        System.out.println("-----------------------");
        //引用类中成员方法
        useMyString((s,x,y)-> s.substring(x,y));
        useMyString(String::substring);
        System.out.println("------------------------");
        //采用构造方法
        useStudentBuilder((s,x)->new Student(s,x));
        useStudentBuilder(Student::new);
    }
    public static void useConverter(Converter converter){
        System.out.println("the result is:"+converter.convert("666"));
    }
    public static void usePrintStr(Printable printable){
        printable.printUpperCase("I Love Java I Love Python");
    }
    public static void useMyString(MyString myString){
        String str = myString.mySubString("HelloJava", 1, 6);
        System.out.println(str);
    }
    public static void useStudentBuilder(StudentBuilder studentBuilder){
        Student student = studentBuilder.build("赵丽颖", 34);
        System.out.println(student.getName()+":"+student.getAge());
    }
}

Test Results
Insert picture description here

Case two

use

public class FunctionInterface {
    public static void main(String[] args) {
        String string = getString(() -> "巨量鹏");
        System.out.println(string);
        System.out.println("-------------------");

        int val = getInteger(() -> 30);
        System.out.println(val);

        System.out.println("------------------");
       int[] arr = {19, 97, 28, 37, 46,76};

        int maxVal=getMax(()->{
            int max =arr[0];
            for (int i = 1; i < arr.length; i++) {
                if(arr[i]>max){
                    max=arr[i];
                }
            }
            return max;
        });
        System.out.println(maxVal);
        System.out.println("------------------");
        /*operatorString("天量鹏",(String s)->{
            System.out.println(s);
        });*/
        //采用lambda表达式
        operatorString("天量鹏", s-> System.out.println(s));
        //采用函数式应用
       // operatorString("天量鹏",  System.out::println);
        //采用匿名内部类
        operatorString("若皮赞", new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });
        //反向输入
        operatorString("天量鹏",s-> System.out.println(new StringBuilder(s).reverse().toString()));
        System.out.println("---------------------------");
        operatorString("天量鹏",s-> System.out.println(s),
                s-> System.out.println(new StringBuilder(s).reverse().toString()));
        System.out.println("---------------------------");
        String [] strArr={"杨颖,38","赵丽颖,34"};
        operatorString(strArr,s -> {
            String sName=s.split(",")[0];
            System.out.println("姓名:"+sName);
        },s->{
            int sAge=Integer.parseInt(s.split(",")[1]);
            System.out.println("年龄:"+sAge);
        });
        System.out.println("------------------------");
        boolean test = checkString("hello", s ->
                        s.length() > 4
                ,s -> s.length() < 9);
        System.out.println(test);
        System.out.println("------------------------");
        String [] str= {"刘亦菲,40","刘岩,42","韩雪,44","文章,32","迪丽热巴,36","杨幂,37","我爱罗,34"};
        ArrayList<String> arrayList = condition(str, s -> {
            String s1 = s.split(",")[0];
            return s1.length() > 2;
        }, s -> {
            int i = Integer.parseInt(s.split(",")[1]);
            return i > 35;
        });
        for (String o : arrayList) {
            System.out.println(o);
        }
        System.out.println("--------------------------");
        String myConverter = converter("120", 6, (s) -> {
            return Integer.parseInt(s);
        }, (s) -> Integer.toString(s));
        System.out.println(myConverter);

    }
    //定义一个方法,返回一个整数数据
    private static Integer getInteger(Supplier<Integer> sup) {
        return sup.get();
    }
    //定义一个方法,返回一个字符串数据
    private static String getString(Supplier<String> sup) {
        return sup.get();
    }
    private static int getMax(Supplier<Integer> sup){
        return sup.get();
    }
    private static void operatorString(String str, Consumer<String> consumer){
        consumer.accept(str);
    }
    private static void operatorString(String str, Consumer<String> consumer1,Consumer<String > consumer2){
        //consumer1.accept(str);
        //consumer2.accept(str);
        consumer1.andThen(consumer2).accept(str);
    }
    private static void operatorString(String [] str,Consumer<String> consumer1,Consumer<String > consumer2){
        for (String s :
                str) {
            consumer1.andThen(consumer2).accept(s);
        }
    }
    private static boolean checkString(String s, Predicate<String> s1,Predicate <String> s2){
        /*boolean test1 = s1.test(s);
        boolean test2=s2.test(s);
        return test1&&test2;*/
        //也可以使用or方法
        return s1.and(s2).test(s);
    }
    private static ArrayList condition(String [] str,Predicate<String> s1,Predicate<String> s2){
        ArrayList<String> arrayList = new ArrayList<>();
        for (String s : str) {
            boolean test = s1.and(s2).test(s);
            if(test){
                arrayList.add(s);
            }
        }
        return arrayList;
    }
    //Function接口
    private  static String converter(String s, int startVal, Function<String ,Integer > fun1,Function<Integer ,String > fun2){
        Integer apply = fun1.apply(s)+startVal;
        String apply1 = fun2.apply(apply);
        return apply1;
        //不能满足要求
        //return  fun1.andThen(fun2).apply(s);
    }
}

Test Results
Insert picture description here

Guess you like

Origin blog.csdn.net/xueshanfeitian/article/details/108972773