java8的新特性:
1、lambda表达式
- 定义:简洁、可传递的匿名函数。首先它本质上是一个函数,具有参数列表、函数主体、返回类型,其次是匿名的,lambda表达式没有具体的函数名字;
- 有以下几种格式定义:
- 无参数:()->{函数主体};
- 单一参数:(String s)->{函数主体}或 s -> {函数主体},其中参数s的类型可以推断;
- 多个参数:(String s1, …String s2) ->{函数主体} 或者(s1, … s2) ->{函数主体},参数类型能够推断;
- 函数主体只有一句话或者只返回值,可以省略{},例如:s->s.toString()
2、@FunctionalInterface注解
-
该注解作用于接口上,不能作用于其他注解类型、枚举、类上;
-
声明该注解的接口表明该接口在java语义规范中是一个功能接口
-
从概念上讲,功能接口只能有一个抽象方法,如果该接口声明了一个覆盖Object类的public方法之一的抽象方法,那么不会计入抽象方法计数之中,因为任何实现该接口的类都将具有来自Object或其他地方的实现:
@FunctionalInterface public interface Function{ void test(); int hashCode(); }
-
对于只有一个抽象方法的接口(不包含覆盖Objec类中的public方法),即使没有声明@Functionalinterface,编译器也会认为是一个功能接口;
public interface Function{ void test(); int hashCode(); }
-
创建声明该注解的接口,可以用lambda表达式、方法引用(实例方法、静态方法)、构造函数;
package com.example.demo.function; /** * @author wang junyi * @title: FunctionTest1 * @projectName jdk1.8 * @date 2019-05-27 14:25 */ public class FunctionTest1 { public static void main(String[] args) { //lambda表达式创建 Function1 function1=()-> System.out.println("FunctionTest1.main"); function1.test(); //实例方法 Student student=new Student("wangsan",20); Function2 function2=Student::getName; System.out.println("function2 = " +function2.test(student)); //静态方法 Function2 function21=Student::getStudentName; Student student1=new Student("lisi",20); System.out.println("function21 = " +function21.test(student1)); //构造函数 Function3 function3=Student::new; Student student2=function3.test("hena",20); System.out.println("student2 = " + student2); } } interface Function1{ void test(); int hashCode(); } interface Function2{ String test(Student test); } interface Function3{ Student test(String name,int age); } 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 + '}'; } public static String getStudentName(Student student){ return student.getName(); } }
3、jdk8中几种常见的功能接口,这些接口都位于rt.jar包下的java.util.Objects包中
-
Function<T, R>接口:
-
抽象方法:R apply(T t);
-
作用:接收一个T类型的参数,返回一个R类型的结果
-
默认方法:
-
compose:参数是Function before,返回一个Function接口,返回一个组合函数,首先将参数before应用于去输入,然后再将此函数应用于结果,如果任意一函数抛出异常,则将其转发给组合函数的调用者:
Function<Integer,Integer> function1= x-> x * 3; Function<Integer,Integer>function2= x->x*x; Function<Integer, Integer> compose = function2.compose(function1); System.out.println("compose = " + compose.apply(2));//输出
-
andThen: 返回一个组合函数,该函数首先将此函数应用于其输入,然后将after函数应用于结果
Function<Integer, Integer> function = function2.andThen(function1); System.out.println("function = " + function.apply(2));//输出12
-
-
静态方法: identity,返回一个Function,而这个Function总是返回参数;
-
类似的接口:
- BiFunction<T, U, R>:输入两个参数T、U,返回一个结果R
- IntFunction输入int类型,返回一个结果R,LongFunction输入一个long类型,返回一个R类型的结果等输入基本类型,返回一个结果;
-
-
Consumer接口:
-
抽象方法:void accept(T t);
-
作用:接收一个T类型的参数,不返回结果;
-
默认方法:
-
andThen: Consumer andThen(Consumer<? super T> after),返回一个组合的Consumer,执行顺序是先执行该操作,再执行after,如果执行任意操作发生异常的,抛出异常给调用者,如果该操作引发异常,则不会执行after操作:
Consumer<String>consumer1=x-> System.out.println("consumer1:"+x); consumer1.accept("consumer1-test");//输出 consumer1:consumer1-test Consumer<String>consumer2=x-> System.out.println("consumer2:"+x); consumer2.accept("consumer2-test");//输出 consumer2:consumer2-test consumer2.andThen(consumer1).accept("andThen-test");// 输出consumer2:andThen-test,consumer1:andThen-test
-
-
类似接口:
- BiConsumer<T, U>:接收两个参数,不返回结果;
- IntConsumer、LongConsumer等接收基本类型的参数不返回结果;
-
-
Predicate接口:
-
抽象方法: boolean test(T t);
-
作用:接收一个T类型的参数,返回一个布尔值;
-
默认方法:
-
and: Predicate and(Predicate<? super T> other),返回一个组合的Predicate,并且表示该predicate与other是一个逻辑与,在评估该组合predicate时,如果此predicate是false,则不会评估other
Predicate<String>predicate1=x->{ System.out.println("x = " + x); return x.length()>1; }; Predicate<String>predicate2=x->{ System.out.println("x = " + x); return x.length()<5; }; System.out.println(predicate1.and(predicate2).test("h"));//输出 x=h false System.out.println(predicate2.and(predicate1).test("h"));//输出 x=h x=h false
-
Predicate negate():取反
-
Predicate or(Predicate<? super T> other):逻辑或
-
-
静态方法:
- Predicate isEqual(Object targetRef):返回一个 predicate,用来测试Objects.equals(Object,Object)两个参数是否相等
-
类似接口:
- BiPredicate<T, U>:接收两个参数,返回一个布尔值;
- IntPredicate、LongPredicate等基本类型的Predicate;
-
-
Supplier接口:
-
抽象方法:T get();
-
作用:不接收参数,返回一个T类型的结果;
Supplier<Date>dateSupplier=Date::new;//调用Date()的无参构造函数
-
类似接口:IntSupplier、LongSupplier等不接收参数,返回一个基本类型结果;
-
-
BinaryOperator接口,继承BiFunction<T,T,T>:
-
作用:接收两个T类型的参数,返回一个T类型的结果
BinaryOperator<Integer>binaryOperator=(x,y)->x+y;
-
静态方法:
-
BinaryOperator minBy(Comparator<? super T> comparator):返回最小者,根据comparator比较;
Student lisan = new Student("lisan", 20); Student zhaosi = new Student("zhaosi", 21); BinaryOperator<Student> studentBinaryOperator = BinaryOperator.minBy(Comparator.comparingInt(Student::getAge)); Student apply = studentBinaryOperator.apply(lisan, zhaosi); System.out.println("apply = " + apply);//根据年龄获取较小者
-
BinaryOperator maxBy(Comparator<? super T> comparator):根据comparator,返回较大者;
BinaryOperator<Student> studentBinaryOperator1 = BinaryOperator.maxBy(Comparator.comparing(Student::getName)); Student apply1 = studentBinaryOperator1.apply(lisan, zhaosi); System.out.println("apply1 = " + apply1);//根据name获取较大者
-
-