欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JDK8新特性学习总结

程序员文章站 2022-06-28 17:07:23
public class DemoLambdaIntro { public static void main(String[] args) { //匿名内部类 //1.定义了一个没有名字的类 //2.这个类实现了runnable接口 //3.创建了这个类的对象 new Thread(new Runnable() { @Override public void run() ....
public class DemoLambdaIntro {
    public static void main(String[] args) {
        //匿名内部类
        //1.定义了一个没有名字的类
        //2.这个类实现了runnable接口
        //3.创建了这个类的对象
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("线程执行");
            }
        }).start();
    }
}

匿名内部类的语法是很冗余的,其实我们关注的是run方法和里面要执行的代码,lambda表达式体现的是函数式变成思想,只需要将要执行的代码放到函数中(函数就是类中的方法),lambda就是一个匿名函数,我们只需要将要执行的代码放到lambda表达式中即可

public class DemoLambdaIntro {
    public static void main(String[] args) {
        //匿名内部类
        //1.定义了一个没有名字的类
        //2.这个类实现了runnable接口
        //3.创建了这个类的对象
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("线程执行");
            }
        }).start();

        //体验lambda表达式
        new Thread(()->{
            System.out.println("lambda表达式执行啦");
        }).start();
    }
}

lambda表达式的好处:可以简化匿名内部类,让代码更加精简

 

练习使用lambda表达式

public class DemoLambdaIntro {
    /*
        的标准格式:
            lambda表达式是一个匿名函数,而函数相当于JAVA中的方法
        (参数列表) -> {
        }
        (参数列表):参数列表
        {}方法体
        ->没有实际含义,起到连接的作用

        public static void main(String[] args) {

        }
    */
    public static void main(String[] args) {
        goSwimming(new Swimmable() {
            @Override
            public void swimming() {
                System.out.println("我是匿名内部类的游泳");
            }
        });

        //小结:以后我们看到方法的参数是接口就可以考虑使用lambda表达式
        //我们可以这么认为,Lambda表达式就是对接口中的抽象方法的重写
        goSwimming(() ->{
            System.out.println("我是lambda的游泳");
        });
        System.out.println("------------------");

        goSiking(new Smokeable() {
            @Override
            public int smoking(String name) {
                System.out.println("匿名内部类抽了"+ name +"的烟");
                return 5;
            }
        });
        goSiking((String name)->{
            System.out.println("lambda抽了"+ name +"的烟");
            return 6;
        });


    }
    //练习有参数有返回值的lambda
    private static void  goSiking(Smokeable s){
        int i = s.smoking("中华");
        System.out.println("返回值:"+i);
    }

    //练习无参数无返回值的lambda

    public static void goSwimming(Swimmable s){
        s.swimming();
    }
}

 

public interface Smokeable {
    public abstract  int smoking(String name);

}
public interface Swimmable {
    public abstract  void swimming();
}

增强练习案例  

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.stream.Collectors;

public class DemoLambdaIntro {
    public static void main(String[] args) {
        ArrayList<Person> persons = new ArrayList<>();
        persons.add(new Person("刘德华",58,174));
        persons.add(new Person("张学友",58,176));
        persons.add(new Person("刘德华",54,171));
        persons.add(new Person("黎明",53,178));

       /* Collections.sort(persons, new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                return o2.getAge()-o1.getAge();
            }
        });*/

       Collections.sort(persons,(Person o1,Person o2) ->{
           return o2.getAge()-o1.getAge();
       });

        for (Person person : persons) {
            System.out.println(person);
        }

    }
}
public class Person {
    String name;
    int age;

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", height=" + height +
                '}';
    }

    public Person(String name, int age, int height) {
        this.name = name;
        this.age = age;
        this.height = height;
    }

    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;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    int height;


}

小结:首先学习了lambda表达式的标准格式

(参数列表) -> {
        }

 

以后我们看到调用的方法他的参数是接口就可以考虑使用lambda表达式来替代匿名内部类,不是所有的匿名内部类都能使用lambda来替换,lambda表示式相当于接口的抽象方法重写

JDK8新特性学习总结

 小结
匿名内部类在编译的时候会一个class文件
Lambda在程序运行的时候形成一个类
1.在类中新增一个方法,这个方法的方法体就是Lambda表达式中的代码
2.还会形成一个匿名内部类,实现接口,,重写抽象方法
3.在接口的重写方法中会调用新生成的方法

 

Lambda省略格式


目标
掌握Lambda省略格式
在Lambda标准格式的基础上,使用省略写法的规则为:
1.小括号内参数的类型可以省略
2.如果小括号内有且仅有一个参数,则小括号可以省略
3.如果大括号内有且仅有一个语句,可以同时省略大括号、return关键字及语句分号(同时省略)

(int a) -> {
return new Person( ) ;
}
a -> new Person()
import java.util.ArrayList;
import java.util.Collections;

public class DemoLambdaIntro {
    public static void main(String[] args) {
        ArrayList<Person> persons = new ArrayList<>();
        persons.add(new Person("刘德华",58,174));
        persons.add(new Person("张学友",58,176));
        persons.add(new Person("刘德华",54,171));
        persons.add(new Person("黎明",53,178));

       Collections.sort(persons,(o1,o2) ->o2.getAge()-o1.getAge());

        persons.forEach(t -> System.out.println(t));


    }
}


 

public class DemoLambdaIntro {
    public static void main(String[] args) {
        //方法的参数或局部变量类型必须为接口才能使用Lambda
        test(() -> {
        });
        Runnable r = new Runnable() {
            @Override
            public void run() {
                System. out. println("aa");
            }
        };

        Flyable f =() -> {
            System.out.println("我会飞啦");
        };


    }
    public static void test (Flyable a) {

    }

    //只有一个抽象方法的接口称为函数式接口,我们就能使用Lambda
    @FunctionalInterface //检测这个接口是不是只有一个抽象方法
    interface Flyable {
        //接口中有且仅有一个抽象方法
        public abstract void eat() ;
//        public abstract void eat2() ;
    }
}

小结:

Lambda的语法非常简洁,但是Lambda表达式不是随便使用的,使用时有几个条件要特别注意:
1.方法的参数或局部变量类型必须为接口才能使用Lambda
2.接口中有且仅有一个抽象方法
 

 

Lambda和匿名内部类对比


目标
了解Lambda和匿名内部类在使用上的区别
1.所需的类型不一样
匿名内部类需要的类型可以是类、抽象类、接口
Lambda表达式需要的类型必须是接口
2.抽象方法的数是不一样
匿名内部类所需的接口中抽象方法的数量随意
Lambda表达式所需的接口只能有一个抽象方法
3.实现原理不同
置名内部类是在编译后会形成class
Lambda表达式是在程序运行的时候动态生成class


小结
当接口中只有一个抽象方法时,建议使用Lambda表达式其他其他情况还是需要使用匿名内部类


JDK 8接口增强介绍


JDK 8以前的接口:

interface 接口名{
    静态常量;
    抽象方法;
}


JDK 8对接口的增强,接口还可以有默认方法和静态方法
JDK 8的接口:

interface 接口名{
    静态常量;
    抽象方法;
    默认方法:
    静态方法;
}
interface A {
    public abstract void test01() ;
    //此时如果需要在A接口新增一个方法,所有继承这些接口的实现类都要重新去实现它,非常麻烦
//    public abstract void test02() ;
}
class B implements A {
    @Override
    public void test01() {
        System.out.println("B test01");
    }
}
class C implements A {
    @Override
    public void test01() {
        System.out.println("C test01");
    }
}


JDK8新特性学习总结

接口中的默认方法实现类不必重写,可以直接使用,实现类也可以根据需要重写。这样就方便接口的扩展。
 

接口默认方法的定义格式

interface 接口名{
    修饰符 default 返回值类型 方法名() {
        代码;
    }
}

接口默认方法的使用
方式一:实现类直接调用接口默认方法
方式二:实现类重写接口默认方法
 

public class DemoLambdaIntro {
    public static void main(String[] args) {
        BB bb = new BB() ;
        bb. test01() ;
        CC cc = new CC() ;
        cc. test01() ;
    }

}

interface AA {

    public default void test01() {
        System.out.println("我是接口AA默认方法");
    }
}
//默认方法使用方式一:实现类可以直接使用
class BB implements AA{

}
//默认方法使用方式二:实现类可以重写默认方法
class CC implements AA {
    @Override
    public void test01(){
        System.out.println("我是CC类重写的默认方法");
    }
}

接口静态方法
为了方便按口扩展,JDK 8为法口新增了静态方法。
接口静态方法的定义格式

interface 接口名《
    修饰符 static 返回值 类型方法名() {
        代码;
    }
}


接口静态方法的使用
直接使用接口名调用即可:接口名.静态方法名():

public class DemoLambdaIntro {
    public static void main(String[] args) {
        BBB bbb = new BBB() ;
        // bbb.test01();
        //使用接口名.静态方法名(;
        AAA.test01();
    }
}
interface AAA {
    public static void test01() {
        System.out.println("我是接口静态方法");
    }
}

class BBB implements AAA{
   /* @Override 静态方法不能重写
    public static void test01() {
        System.out.println("我是接口静态方法");
    }*/
}


接口默认方法和静态方法的区别
1.默认方法通过实例调用,静态方法通过接口名调用。
2.默认方法可以被继承,实现类可以直接使用接口默认方法,也可以重写接口默认方法。
3.静态方法不能被继承,实现类不能重写接口静态方法,只能使用接口名调用。
 

小结
接口中新增的两种方法:
默认方法和静态方法
如何选择呢?如果这个方法需要被实现类继承或重写,使用默认方法,如果接口中的方法不需要被继承就使用静态方法
 

常用内置函数式接口


目标


了解内置函数式接口由来
了解常用内置函数式接口


内置函数式接口来由来


我们知道使用Lambda表达式的前提是需要有函数式接口。而Lambda使用时不关心接口名、抽象方法名,只关心抽象方法的参数列表和返回值类型。因此为了让我们使用Lambda方便,JDK提供了大量常用的函数式接口。

常用内置函数式接口介绍


它们主要在java.util.function包中。下面是最常用的几个接口。


1. Supplier接口

java.util.function.supplier<T>接口,它意味看“供给”,对应的Lambda表达式需要“对外提供"一个符合泛型类型的对象数据。
 

@FunctionalInterface
public interface Supplier<T> {
    public abstract T get();
}


供给型接口,通过Supplier接口中的get方法可以得到一个值,无参有返回的接口。


使用Lambda表达式返回数组元素最大值
使用Supplier接口作为方法参数类型,通过Lambda表达式求出int数组中的最大值。提示:接口的泛型请使用java.lang.Integer类。

import java.util.Arrays;
import java.util.function.Supplier;

public class DemoLambdaIntro {
    //使用Lambda表达式返回数组元素最大值

    public static void main(String[] args) {

        printMax(() -> {
            int[]arr = {11,99,88,77,22};
            Arrays.sort(arr); //升序排序
            return arr[arr. length - 1];
        });
    }
    public static void printMax (Supplier<Integer> supplier) {
        int max = supplier.get() ;
        System. out. println("max ="+ max) ;
    }

}


2. Consumer接口

java.util.function.Consumer<T>接口则正好相反,它不是生产一个数据, 而是消费一个数据, 其数据类型由泛型参数决定。

@FunctionalInterface
public interface Consumer<T> {
    public abstract T accept();
}

使用Lambda表达式将一个字符串转成大写和小写的字符串


Consumer消费型接口,可以拿到accept方法参数传递过来的数据进行处理,有参无返回的接口。基本使用如:

import java.util.function.Consumer;

public class DemoLambdaIntro {
    public static void main(String[] args) {
        System.out.println("开始啦");
        printHello((String str) -> {
            System. out. println(str. toUpperCase());
        });
    }
    public static void printHello (Consumer<String> consumer){
        System.out.println("aaa");
        consumer.accept( "Hello World");

    }
}
import java.util.function.Consumer;

public class DemoLambdaIntro {
    public static void main(String[] args) {
        System.out.println("开始啦");
        printHello((String str) -> {
            System. out. println(str. toLowerCase());
        },(String str) -> {
            System. out. println(str. toUpperCase());
        });
    }
    public static void printHello (Consumer<String> c1,Consumer<String> c2) {
        System.out.println("aaa");
        String str =  "Hello World";
        c1.accept(str);
        c2.accept(str);
    }
}


默认方法: andThen


如果一个方法的参数和返回值全都是Consumer类型,那么就可以实现效果:消费一个数据的时候, 首先做一个操作,然后再做一个操作, 实现组合。而这个方法就是Consumer接口中的default方法andThen。

import java.util.function.Consumer;

public class DemoLambdaIntro {
    public static void main(String[] args) {
        System.out.println("开始啦");
        printHello((String str) -> {
            System. out. println(str. toLowerCase());
        },(String str) -> {
            System. out. println(str. toUpperCase());
        });
    }
    public static void printHello (Consumer<String> c1,Consumer<String> c2) {
        System.out.println("aaa");
        String str =  "Hello World";
        /*c1.accept(str);
        c2.accept(str);*/
        c1.andThen(c2).accept(str);
    }
}


3. Function接口

java.util.function.Function<T, R>接口用来根据一个类型的数据得到另一个类型的数据, 前者称为前置条件,后者称为后置条件。有参数有返回值。

@FunctionalInterface
public interface Function<T, R> {
    public abstract R apply(T t);
}


使用Lambda表达式将字符串转成数字


Function转换型接口,对apply方法传入的T类型数据进行处理,返回R类型的结果,有参有返回的接口。使用的场景例如:将String类型转换为Integer类型。

import java.util.function.Function;

public class DemoLambdaIntro {
    //使用Lambda表达式将字符串转成数字
    public static void main(String[] args) {
        getNumber((String str) -> {
            int i = Integer. parseInt(str);
            return i;
        });
    }
    public static void getNumber (Function<String,Integer> function) {
        Integer numl = function.apply( "10" );
        System.out.println(" num1 ="+ numl) ;
    }
}


默认方法: andThen


Function接口中有一个默认的andThen方法,用来进行组合操作。

import java.util.function.Function;

public class DemoLambdaIntro {
    //使用Lambda表达式将字符串转成数字,第二个操作将这个数字乘以5
    public static void main(String[] args) {
        getNumber((String str)->{
            return Integer. parseInt(str) ;
        },(Integer i) -> {
            return i * 5;
        });
}
    public static void getNumber (Function<String,Integer> f1, Function<Integer, Integer> f2) {
        System. out. println("aa");
        Integer num = f1. apply("6");
        Integer num2 = f2. apply (num) ;
        System.out.println("num2 =" + num2) ;
    }
}
import java.util.function.Function;

public class DemoLambdaIntro {
    //使用Lambda表达式将字符串转成数字,第二个操作将这个数字乘以5
    public static void main(String[] args) {
        getNumber((String str)->{
            return Integer. parseInt(str) ;
        },(Integer i) -> {
            return i * 5;
        });
}
    public static void getNumber (Function<String,Integer> f1, Function<Integer, Integer> f2) {
        System. out. println("aa");
        /*Integer num = f1. apply("6");
        Integer num2 = f2. apply (num) ;*/
        Integer num2 = f1.andThen(f2).apply("6");
        System.out.println("num2 =" + num2) ;
    }
}


4. Predicate接口

有时候我们需要对某种类型的数据进行判断,似而得到一个boolean值结果。这时可以使用java.util.function.Predicate<T>接口。
 

@FunctionalInterface
public interface Predicate<T> {
    public abstract boolean test(T t);
}
Predicate接口用于做判断,返回boolean类型的值

使用Lambda判断一个人名如果超过3个字就认为是很长的名字
对test方法的参数T进行判断,返回boolean类型的结果。用于条件判断的场景:
 

import java.util.function.Predicate;

public class DemoLambdaIntro {
    //使用Lambda判断一个人名如果超过3个字就认为是很长的名字
    public static void main(String[] args) {
        System.out.println("开始啦");
        isLongName((String name) -> {
            return name.length() > 3;
        });
    }
    public static void isLongName (Predicate<String> predicate){
        System.out.println(" aa");
        boolean isLong = predicate. test("迪丽热巴");
        System.out.println("是否是长名字:"+ isLong) ;
    }
}

条件判断的标准是传入的Lambda表达式逻辑,只要名称长度大于3则认为很长。


默认方法: and


既然是条件判断,就会存在与、或、非三种常见的逻辑关系。其中将两个Predicate条件使用”与”逻辑连接起来实现"并且”的效果时,可以使用default方法and.
 

使用Lambda表达式判断一个字符串中即包含W,也包含H
使用Lambda表达式判断一个字符串中包含W或者包含H
使用Lambda表达式判断一个字符串中即不包含W
如果要判断一个字符串既要包含大写"H",又要包含大写"W",那么: 

import java.util.function.Predicate;

public class DemoLambdaIntro {
    /*使用Lambda表达式判断-个字符串中即包含W,也包含H
    使用Lambda表达式判断-个字符串中包含W或者包含H
    使用Lambda表达式判断-个字符串中即不包含W*/
    public static void main(String[] args) {
        System.out.println("开始啦");
        test((String str) -> {
        //判断是否包含W
            return str. contains("W") ;
        },(String str) -> {
        //判断是否包含H
            return str. contains("H");
        });
    }
    public static void test (Predicate<String> p1, Predicate<String> p2){
        String str = "Hello World" ;
        boolean b1 = p1. test(str);
        boolean b2 = p2. test(str) ;
        if (b1 && b2){
            System.out.println("即包含W,也包含H");
        }
    }
}
import java.util.function.Predicate;

public class DemoLambdaIntro {
    /*使用Lambda表达式判断-个字符串中即包含W,也包含H
    使用Lambda表达式判断-个字符串中包含W或者包含H
    使用Lambda表达式判断-个字符串中即不包含W*/
    public static void main(String[] args) {
        System.out.println("开始啦");
        test((String str) -> {
        //判断是否包含W
            return str. contains("W") ;
        },(String str) -> {
        //判断是否包含H
            return str. contains("H");
        });
    }
    public static void test (Predicate<String> p1, Predicate<String> p2){
        String str = "Hello World" ;
       /* boolean b1 = p1. test(str);
        boolean b2 = p2. test(str) ;
        if (b1 && b2){
            System.out.println("即包含W,也包含H");
        }*/
//        使用Lambda表达式判断-个字符串中即包含W,也包含H
        boolean b = p1.and(p2).test(str);
        if(b){
            System.out.println("即包含W,也包含H");
        }

//        使用Lambda表达式判断-个字符串中包含W或者包含H
        boolean b1 = p1.or(p2).test(str);
        if(b1){
            System.out.println("包含W或者包含H");
        }
//        使用Lambda表达式判断-个字符串中即不包含W
        boolean b2 = p1.negate().test("Hello");
        //negate相当于取反 !boolean
        if(b2){
            System.out.println("不包含W");
        }
    }
}

介绍方法引用


目标


了解Lambda的冗余场景
掌握方法引用的格式
了解常见的方法引用方式


Lambda的冗余场景
使用Lambda表达式求一个数组的和
 

import java.util.function.Consumer;

public class DemoLambdaIntro {
    //求一个数组的和
    public static void getMax(int[] arr) {
        int sum = 0;
        for (int n : arr) {
            sum += n;
        }
        System.out.println(sum);
    }

    public static void main(String[] args) {
        //使用Lambda表达式求一个数组的和
        printMax((int[] arr) ->{
          /*  int sum = 0;
            for (int n : arr) {
                sum += n;
            }
            System.out.println(sum);*/
            getMax(arr);
        });
        //使用方法引用
        //让这个指定的方法去重写接口的抽象方法,到时候调用接口的抽象方法就是调用传递过去的这个方法
        printMax(DemoLambdaIntro::getMax);
    }

    public static void printMax(Consumer<int[]> consumer) {
        int[] arr = {11, 22, 33, 44, 55};
        consumer.accept(arr);
    }
}

请注意其中的双置号::写法,这被称为方法引用",是一种种新的语法。
方法引用的格式
符号表示: ::
符号说明:双冒号为方法引用运算符,而它所在的表达式被称为方法引用
应用场景:如果Lambda所要实现的方案,已经有其他方法存在相同方案,那么则可以使用方法引用。


常见引用方式
方法引用在JDK 8中使用方式相当灵活,有以下几种形式: 
1. instanceName:: methodName 对象::方法法名
2. ClassName::stat icMethodName 类名::静态方法
3. ClassName::methodName 类名::普通方法
4. ClassName::new 类名::new调用的构造器
5. TypeName[]::new  String[]::new调用数组的构造器


小结
首先了解Lambda表达式的冗余情况体验了方法引用,了解常见的方法引用方式


对象名::引用成员方法
这是最常见的一种用法,与上例相同。如果一个类中已经存在了一个成员方法,则可以通过对象名引用成员方法,
代码为:
 

    //对象::实例方法
    @Test
    public void test01(){
        Date now = new Date();
        Supplier<Long> supp = () -> {
            return now.getTime();
        };
        System.out.println(supp.get());

        //使用方法引用
        Supplier<Long> supp2 = now::getTime;
        System.out.println(supp2.get());
        //注意:方法引用有两个注意事项
        // 1.被引用的方法,参数要和接口中抽象方法的参数一样
        // 2.当接口抽象方法有返回值时,被引用的方法也必须有返回值
        /* Supplier<Long> su3 = now::setTime;
         su3. get();*/
        /*Supplier<Long> su4 = now::setDate;
        su4. get() ;*/
    }
}

方法引用的注意事项
1.被引用的方法,参数要和接口中抽象方法的参数一样
2.当接口抽象方法有返回值时,被引用的方法也必须有返回值


类名::引用静态方法
由于在java. lang. System类中已经存在了静态方法currentTimeMillis,所以当我们需要通过Lambda来调用该方法时,可以使用方法引用,写法是:
 

//类名::静态方法
    @Test
    public void test02() {
       /* Supplier<Long> su = () -> {
            return System.currentTimeMillis();
        };*/
        Supplier<Long> su = System::currentTimeMillis;
        Long time = su.get();
        System. out. println("time ="+ time);
    }

类名::引用实例方法
Java面向对象中,类名只能调用静态方法,类名引用实例方法是有前提的,实际上是拿第一个参数作为方法的调用者。
 

//类名::实例方法
    @Test
    public void test03(){
       /* Function<String,Integer> f1 = (String str) -> {
            return str.length();
        };*/
        //类名::实例方法(注意: 类名::实例方法实际上会将第一个参数作为方法的调用者)
        Function<String,Integer> f1 = String::length;
        int length = f1.apply( "hello");
        System. out. println("length ="+ length) ;

        // BiFunction<String,Integer, String> f2 = String:: substring;
        //相当于这样的Lambda
        BiFunction<String,Integer,String> f2 = (String str, Integer index) -> {
            return str.substring (index) ;
        };
        String str2 = f2. apply( "helloworld", 3);
        System. out. println(" str2 ="+ str2); // loworld
    }

类名::new引用构造器
由于构造器的名称与类名完全一样。 所以构造器引用使用类名称: :new的格式表示。首先是一个简单的Person类:
 

public class Person {
    String name;
    int age;

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public Person() {
        System.out.println("执行无参构造");
    }

    public Person(String name, int age) {
        System.out.println("执行有参构造");
        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;
    }

}
//类名::new 引用类的构造器
    @Test
    public void test04(){

       /* Supplier<Person> su1 = ()->{
            return  new Person();
        };*/

        Supplier<Person> su1 = Person::new;

        Person person = su1.get();
        System.out.println("person =" + person);

        /*BiFunction<String,Integer,Person> su2 = (String name,Integer age) ->{
            return  new Person(name,age);
        };*/

        BiFunction <String,Integer,Person> su2 = Person::new;
        Person person1 = su2.apply("迪丽热巴",18);
        System.out.println("person =" + person1);

    }

数组::new引用数组构造器
数组也是object的子类对象,所以山同样具有构造器,只是语法稍有不同。
 

 //类型[]::new
    @Test
    public void test05() {
       /* Function<Integer, int[]> f1 = (Integer length) -> {
            return new int [length];
        };*/
        Function<Integer, int[]> f1 = int[]::new;
        int[] arr1 = f1.apply(10);
        System.out.println(Arrays.toString(arr1));

    }

 

本文地址:https://blog.csdn.net/qq_37725560/article/details/109599306

相关标签: java