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));
}
情况三,类::实例方法名(有难度)
若Lambda参数列表中的第一参数足实例方法的调用者,而第二个参数是实例方法的参数时:可以使用ClassName :: method
@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)));
}

浙公网安备 33010602011771号