
如果一个接口中,只声明了一个抽象方法,则此接口就称为函数式接口
可以通过Lambda表达式来创建该接口的对象。(若Lambda表达式抛出一个受检异常,那么该异常需要在目标接口的抽象方法上进行声明)
可以在一个接口上使用@FunctionalInterface注解,来检查他是否式一个函数式接口。
在java.util.function包下定义了java8的丰富的函数式接口。
自定义函数式接口:
@FunctionalInterface
public interface FuncInterface {
void test();
// void test1();
}
在Java8中Lambda表达式就是一个函数式接口的实例
java内置四大核心函数式接口| 函数式接口 | 参数类型 | 返回类型 | 用途 |
|---|---|---|---|
| Consumer < T > 消费型接口 | T | void | 对类型为T的对象应用操作,包含方法 void accept(T t) |
| Supplier < T > 供给型接口 | 无 | T | 返回类型为T的对象,包含方法 T get() |
| Function < T > 函数型接口 | T | R | 对类型为T的对象应用操作,并返回结果是R类型的对象,包含方法 R apply(T t) |
| Predicate < T > 断定型接口 | T | boolean | 对类型为T的对象应用操作,并返回boolean值,包含方法 boolean test(T t) |
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
public class LambdaDemo2 {
@Test
public void test1(){
happyTime(500, new Consumer() {
@Override
public void accept(Double aDouble) {
System.out.println("学习消费价格:"+aDouble);
}
});
System.out.println("-------------");
happyTime(300, money-> System.out.println("娱乐消费价格:"+money));
}
public void happyTime(double money, Consumer con){
con.accept(money);
}
@Test
public void test2(){
List list = Arrays.asList("东京","北京","南京","西京","天津");
List strings = filterString(list, new Predicate() {
@Override
public boolean test(String s) {
return s.contains("京");
}
});
System.out.println(strings);
System.out.println("-------------");
List strings2 = filterString(list, s-> s.contains("京"));
System.out.println(strings2);
}
public List filterString(List list, Predicate pre){
ArrayList filterStr= new ArrayList<>();
for (String s:list) {
if(pre.test(s)){
filterStr.add(s);
}
}
return filterStr;
}
}
方法引用与构造器引用
方法引用
什么是方法引用:
当要传递给Lambda体的操作,应有实现的方法了,可以使用方法引用!
方法引用就是Lambda表达式,也就是函数式接口的一个实例,通过方法的名字来指向一个方法,可以认为是Lambda表达式的一个语法糖。
要求:
实现接口的抽象方法的参数泪飙和返回值类型,必须与方法引用的方法参数列表和返回值类型保持一致!
格式:
使用操作符 “::” 将类(或对象)与方法名分隔开来。
主要使用情况:
import org.junit.Test;
import java.io.PrintStream;
import java.util.Comparator;
import java.util.function.Consumer;
import java.util.function.Function;
public class LambdaDemo3 {
// 一、对象 :: 非静态方法
// Consumer中的 void accept(T t)
// PrintStream中的void println(T t)
@Test
public void test1(){
Consumer con1 =str-> System.out.println(str);
con1.accept("北京");
System.out.println("-------------");
PrintStream ps = System.out;
Consumer con2 = ps :: println;
con2.accept("beijing");
}
//二、类::静态方法
//Comparator中的int compare(T t1,T t2)
//Integer中的int compare(T t1,T t2)
@Test
public void test2(){
Comparator com1=(t1,t2)->Integer.compare(t1,t2);
System.out.println(com1.compare(12,21));
System.out.println("-------------");
Comparator com2= Integer::compare;
System.out.println(com2.compare(12,6));
}
//Function中的R apply(T t)
//Math中的Long round(Double d)
@Test
public void test3(){
Function fun1=d -> Math.round(d);
System.out.println(fun1.apply(12.3));
System.out.println("-------------");
Function fun2 = Math::round;
System.out.println(fun2.apply(12.6));
}
//三、类::非静态方法
//Comparator中的int compare(T t1,T t2)
//String中的int t1.compare(t2)
@Test
public void test4(){
Comparator com1=(t1,t2)->t1.compareTo(t2);
System.out.println(com1.compare("abc","abd"));
System.out.println("-------------");
Comparator com2= String::compareTo;
// 这个String 是 上面t1类型的返回值
System.out.println(com2.compare("abc","abe"));
}
}
构造器引用与数组引用
import org.junit.Test;
import java.util.Arrays;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
public class LambdaDemo4 {
//一、构造器引用
//Supplier中的T get()
//Cat的 Cat()
@Test
public void test1(){
//原始
Supplier sup = new Supplier() {
@Override
public Cat get() {
return new Cat();
}
};
sup.get();
System.out.println("---------");
//lambda
Supplier sup1 = ()-> new Cat();
sup1.get();
System.out.println("---------");
//构造器引用
Supplier sup2 = Cat::new;
sup2.get();
}
//Function中R apply(T t)
//Cat的 Cat(String name)
@Test
public void test2(){
//lambda
Function fun1 = (name)-> new Cat(name);
Cat cat = fun1.apply("小花");
System.out.println(cat);
System.out.println("---------");
//构造器引用
Function fun2 =Cat::new;
Cat cat1 = fun2.apply("小草");
System.out.println(cat1);
}
//BiFunction中R apply(T t,U u)
//Cat的 Cat(String name)
@Test
public void test3(){
//lambda
BiFunction fun1 = (name,age)-> new Cat(name,age);
Cat cat = fun1.apply("小花",1);
System.out.println(cat);
System.out.println("---------");
//构造器引用
BiFunction fun2 =Cat::new;
Cat cat1 = fun2.apply("小草",2);
System.out.println(cat1);
}
//二、数组引用
//Function中的R apply(T t)
@Test
public void test4(){
//lambda
Function fun1=length->new String[length];
String[] str1 = fun1.apply(5);
System.out.println(Arrays.toString(str1));
System.out.println("---------");
//数组引用
Function fun2=String[]::new;
String[] str2 = fun2.apply(10);
System.out.println(Arrays.toString(str2));
}
}