JDK新特性一、Lambda表达式1、体验Lambda表达式要求:启动一个线程,在控制台输出一句话:多线程程序启动方法一:定义一个类MyRunnable实现Runnable接口,编写run()方法创建MyRunnable类的对象创建Thread类的对象并将MyRunnable对象作为构造参数传入启动线程方法二:改进匿名内部类的方法newThread(newRunnable(){@Overridepublicvoidrun(){System.out.println("多线程程序启动");}}).start();该方法的形参为空,表示调用该方法时不需要传递任何参数。当方法返回值类型为void时,表示该方法执行不返回结果。方法体中的内容就是我们需要做的。方法三:改进的Lambda表达式newThread(()->{System.out.println("多线程程序启动");}).start();():里面没有内容,可以看做是方法形参为空。->:使用箭头指向下一步要做的事情。{}:包含一段代码,称为代码块,可视为方法体的内容。构成Lambda表达式的三个元素:形式参数、箭头和代码块。Lambda表达式的格式●格式:(形式参数)->{代码块}●形式参数:如果有多个参数,用逗号分隔;如果没有参数,就留空->:英文由一个中间破折号和一个大于号组成,写法是固定的。表示指向动作●代码块:就是我们具体需要做的,也就是我们之前写的方法体内容中使用Llambda表达式的前提:有接口;接口中只有一个抽象方法。2.Lambda表达式的省略方式省略规则:●参数类型可以省略。但是当有多个参数时,你不能只省略一个。如果只有一个参数,则括号可以省略。如果代码块中只有一条语句,可以省略花括号和分号,甚至return。3.Lambda表达式注意事项注意:●使用Lambda时,必须有一个接口,接口中必须有一个且只能有一个抽象方法。●必须有上下文环境,可以推导出Lambda对应的接口。根据局部变量的赋值知道Lambda。对应接口:Runnabler=()->System.out.println("Lambda表达式");根据调用方法的参数知道Lambda对应的接口:newThread(()->System.out.println("Lambdaexpression")).start();4、Lambda表达式和匿名内部类的区别需要不同的类型:匿名内部类:可以是接口也可以是抽象类也可以是具体类Lambda表达式:仅可能是接口使用限制不同:如果有接口中只有一个抽象方法,可以使用Lambda表达式,也可以使用匿名内部类如果接口中有多个抽象方法,只能使用匿名内部类,不能使用Lambda表达式实现原理不同:●匿名内部类:编译后生成一个单独的.class字节码文件。●Lambda表达式:编译后,没有一个.class字节码文件。相应的字节码是在运行时动态生成的。二、接口的新特性1、接口组成更新概述接口的组成:ConstantpublicstaticfinalAbstractmethodpublicabstractDefaultmethod(Java8)Staticmethod(Java8)Privatemethod(Java9)2.Defaultininterface方法接口中默认方法的定义格式:格式:publicdefault返回值类型方法名(参数列表){}示例:publicdefaultvoidshow3(){}接口中默认方法注意事项:默认方法不是一个抽象方法,所以它不是强制被重写的。但是可以重写,写的时候去掉default关键字public可以省略,default不能省略3.接口中的静态方法接口中静态方法的定义格式:格式:publicstatic返回值类型方法名(参数列表){}●示例:publicstaticvoidshow(){}接口中静态方法注意事项:●静态方法只能通过接口名调用,不能通过实现类名或对象名调用●public可以省略,static不能省略4.Interface私有方法接口中私有方法的定义格式:格式一:私有返回值类型方法名(参数列表){}例一:privatevoidshow(){}格式二:私有静态返回值类型方法名(参数列表){}示例2:privatestaticvoidmethod(){}接口中私有方法注意事项:默认方法可以调用私有静态方法和非静态方法静态方法只能调用私有静态方法三.方法引用1.方法引用符方法引用符●::该符号是引用运算符,它所在的表达式称为方法引用。在经验方法参考中查看我们的代码:Lambda表达式:usePrintable(s->System.out.println(s));分析:获取参数s后,通过Lambda表达式传递给System.out.println方法进行处理●方法参考:usePrintable(System.out::printIn);分析:直接用System.out中的println方法代替Lambda,代码更简洁,省略:●如果使用Lambda,那么可以根据“是”可以省略的原则推导,不需要指定参数类型,不需要指定重载形式,会自动推导●如果使用方法引用,也可以按上面推导●方法引用是Lambda的孪生兄弟2.引用一个类method引用类方法实际上是引用类的静态方法●格式:类名::static方法●示例:Integer::parseIntInteger类方法:publicstaticintparselnt(Strings)将这个String转换为int类型数据练习:●定义一个接口(Converter),其中定义一个抽象方法intconvert(Strings);●定义一个测试类(ConverterDemo),在测试类中提供两个方法一个方法是:useConverter(Converterd)一个方法是main方法,在main方法中调用useConverter方法3.引用对象的实例方法引用对象的实例方法实际上是引用类中的一个成员方法格式:object::membermethod示例:"HelloWorld"::toUpperCaseString类中的方法:publicStringtoUpperCase(),把这个String的所有字符都转成大写做法:定义一个类(PrintString),里面定义了一个方法publicvoidprintUpper(Strings):把字符串参数转成大写数据,然后在控制台输出定义一个接口(Printer),接口定义一个抽象方法voidprintUpperCase(Strings)定义一个测试类(PrinterDemo),在测试类中提供两个方法一个方法是:usePrinter(Printerp)一个方法是main方法,方法中调用了usePrinter方法方法四、引用类的实例方法引用类的实例方法实际上是引用类中的成员方法格式:类名::成员方法示例:String::substringString类中的方法:publicStringsubstring(intbeginIndex,intendIndex)从beginIndex到endIndex,截取字符串,返回长度为endIndex-beginIndex的子串做法:定义一个接口(MyString),接口定义了一个抽象方法:StringmySubString(Strings,intx,inty);●定义一个测试类(MyStringDemo),在测试类中提供两个方法一个方法是:useMyString(MyStringmy)一个方法是main方法,在main方法中调用useMyString方法5.引用构造函数引用一个构造函数其实就是一个引用一个构造方法格式:类名::new例子:Student::new实践:定义一个类(Student),有两个成员变量(name,age),并提供一个无参构造方法对应的get和set方法带参数和成员变量的构造方法定义一个接口(StudentBuilder),接口定义一个抽象方法Studentbuild(Stringname,intage);定义一个测试类(StudentDemo),在测试中提供了两个方法一个方法是:useStudentBuilder(StudentBuilders)另一个方法是main方法,在main方法中调用useStudentBuilder方法四、功能接口1、功能接口概述功能接口:一个只有一个抽象方法的接口JavaJava中的函数式编程是Lambda表达式,所以函数式接口是Lambda可以使用的接口。只有保证接口中只有一个抽象方法,才能顺利推导Java中的Lambda。如何查看一个接口是否是函数式接口呢?@Functionallnterface放在接口定义上面:如果接口是函数式接口,编译通过;如果不是,则编译失败。注意:@Functionallnterface在我们定义自己的函数式接口时是可选的。即使我不写这个注解,只要满足函数式接口定义的条件,它仍然是函数式接口。但是,建议添加此注释。2.函数式接口作为方法的参数定义一个类(RunnableDemo),在类中提供两个方法一个方法是:startThread(Runnabler)方法参数Runnable是一个函数式接口,另一个方法是main方法,在方法调用startThread方法如果方法的参数是函数式接口,我们可以使用Lambda表达式作为参数传递startThread(0->System.out.println(Thread.currentThread().getName()+"threadstarted));3.函数式接口作为方法的返回值要求:定义一个类(ComparatorDemo),类中提供两个方法,一个方法是:Comparator
