java8新特性学习二(函数式functional接口)
Posted 马宝云
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java8新特性学习二(函数式functional接口)相关的知识,希望对你有一定的参考价值。
函数式(functional)接口
如果一个接口中,只声明了一个抽象方法,则此接口就称为函数式接口。
可以通过Lambda表达式来创建该接口的对象。(若Lambda表达式抛出一个受检异常(即:非运行时异常),那么该异常需要在目标接口的抽象方法上进行声明)。
我们可以在一个接口上使用@FunctionalInterface注解,这样做可以检查它是否是一个函数式接口。同时javadoc也会包含一条声明,说明这个接口是一个函数式接口。
在java 8中,Lambda表达式就是一个函数式接口的实例。这就是Lambda表达式和函数式接口的关系。也就是说,只要一个对象是函数式接口的实例,那么该对象就可以用Lambda表达式来表示。
在java.util.function包下定义了java 8的丰富的函数式接口。
java内置四大核心函数式接口
其他接口
方法引用与构造器引用
当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用!
方法引用可以看做是Lambda表达式深层次的表达。换句话说,方法引用就是lambda表达式,也就是函数式接口的一个实例,通过方法的名字来指向一个方法,可以认为是Lambda表达式的一个语法糖。
要求:实现接口的抽象方法的参数列表和返回值类型,必须与方法引用的方法的参数列表和返回值类型保持一致!
格式:使用操作符“::”将类(或对象)与方法名分隔开来。
如下三种主要使用情况:
情况一,对象::实例方法名
@Test public void test1(){ //Consumer<T> void accept(T t) //PrintStream void printlt(T t) Consumer<String> consumer1=s-> System.out.println(s); consumer1.accept("测试一"); System.out.println("************************"); PrintStream printStream=System.out; Consumer<String> consumer2=printStream::println; consumer1.accept("方法引用情况一测试"); System.out.println("--------------------------"); //Supplier<T> T get() //User String toString() User user=new User("1001","张三",25,"成都"); Supplier<String> supplier1=()-> user.toString(); System.out.println( supplier1.get()); System.out.println("************************"); Supplier<String> supplier2=user::toString; System.out.println( supplier2.get()); }
User类
public class User { private String id; private String name; private Integer age; private String address; public User(String id, String name, Integer age, String address) { this.id = id; this.name = name; this.age = age; this.address = address; } public User() { System.out.println("user无参构造"); } public User(String id) { this.id = id; System.out.println("id构造=="+id); } public User(String name,Integer age) { this.name = name; this.age = age; System.out.println("name,age构造=="+name+"=="+age); } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; User user = (User) o; return age == user.age && Objects.equals(id, user.id) && Objects.equals(name, user.name) && Objects.equals(address, user.address); } @Override public int hashCode() { return Objects.hash(id, name, age, address); } @Override public String toString() { return "User{" + "id=\'" + id + \'\\\'\' + ", name=\'" + name + \'\\\'\' + ", age=" + age + ", address=\'" + address + \'\\\'\' + \'}\'; } }
情况二,类::静态方法名
@Test public void test2(){ //Comparator<T> int compare(T o1, T o2); //Integer public static int compare(int x, int y) Comparator<Integer> com1=(t1,t2)->Integer.compare(t1,t2); System.out.println(com1.compare(11,22)); System.out.println("*******************"); Comparator<Integer> com2=Integer::compare; System.out.println(com1.compare(33,22)); System.out.println("----------------"); //Function<T,R> R apply(T t); //Math public static long round(double a) Function<Double,Long> func=new Function<Double, Long>() { @Override public Long apply(Double d) { return Math.round(d); } }; System.out.println(func.apply(3.2d)); System.out.println("********************"); Function<Double,Long> fun1=d->Math.round(d); System.out.println(fun1.apply(2.72d)); System.out.println("********************"); Function<Double,Long> fun2=Math::round; System.out.println(fun2.apply(0.5d)); }
情况三,类::实例方法名(有难度)
@Test public void test3(){ //Comparator<T> int compare(T t1, T t2); //String t1.compareTo(t2) Comparator<String> com1=(t1,t2)->t1.compareTo(t2); System.out.println(com1.compare("acd","abd")); System.out.println("********************"); Comparator<String> com2=String::compareTo; System.out.println(com1.compare("abd","abf")); System.out.println("-------------"); // BiPredicate boolean test(T t1, T t2) //String boolean t1.equals(t2) BiPredicate<String,String> pre1=(s1,s2)->s1.equals(s2); System.out.println(pre1.test("abc","abc")); System.out.println("***************"); BiPredicate<String,String> pre2=String::equals; System.out.println(pre2.test("abc","abc")); System.out.println("-----------------"); //Function R apply(T t) //User String toString() User user=new User("1001","张三",25,"成都"); Function<User,String> func1=u->u.toString(); System.out.println(func1.apply(user)); System.out.println("**************"); Function<User,String> func2=User::toString; System.out.println(func2.apply(user)); }
构造器引用
和方法引用类似,函数式接口的抽象方法的形参列表和构造器的形参列表一致。
抽象方法的返回值类型即为构造器所属的的类的类型。
@Test public void test4(){ //Supplier T get() //User中的空参构造器:User() Supplier<User> supplier1=new Supplier<User>() { @Override public User get() { return new User(); } }; System.out.println(supplier1.get()); System.out.println("***************"); Supplier<User> supplier2=()->new User(); System.out.println(supplier2.get()); System.out.println("***************"); Supplier<User> supplier3=User::new; System.out.println(supplier3.get()); System.out.println("------------"); //Function中的R apply(T t) Function<String,User> func1=id->new User(id); System.out.println(func1.apply("1001")); System.out.println("************"); Function<String,User> func2=User::new; System.out.println(func1.apply("1001")); System.out.println("---------------------"); //BiFunction R apply(T t,U u) BiFunction<String,Integer,User> func3=(name,age)->new User(name,age); System.out.println(func3.apply("张三",25)); System.out.println("*************"); BiFunction<String,Integer,User> func4=User::new; System.out.println(func4.apply("张三",25)); }
数组引用
把数组看成是一个特殊的类,则写法与构造器引用一致。
@Test public void test5(){ //Function R apply(T t) Function<Integer,String[]> fun1=length->new String[length]; System.out.println(Arrays.toString(fun1.apply(5))); System.out.println("***************"); Function<Integer,String[]> fun2=String[]::new; System.out.println(Arrays.toString(fun2.apply(5))); }
以上是关于java8新特性学习二(函数式functional接口)的主要内容,如果未能解决你的问题,请参考以下文章