函数式接口就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。函数式接口可以被隐式转换为 lambda 表达式。那java函数式接口的应用场景是什么?下面来我们就来给大家讲解一下。
首先,我们先定义一个函数式编程接口
@FunctionalInterfacepublic interface BooleanFunctionalInterface{ boolean test(T t); }
很简单,该接口的唯一一个抽象方法(并且非Object类的方法)返回值为boolean
下面,定义一个方法,接受一个List,利用实现了该接口的test方法的对象,筛选出需要的元素:
import org.springframework.util.CollectionUtils; import java.util.ArrayList; import java.util.List; import java.util.function.Predicate; public class Filter { public staticListfilter(Listlist, BooleanFunctionalInterface b) { if (CollectionUtils.isEmpty(list)) { return new ArrayList < > (0); } Listresult = new ArrayList < > (list.size()); for (int i = 0; i < list.size(); p = "" i++) { <= "" > T t = list.get(i); if (b.test(t)) { result.add(t); } } return result; } }
测试类,筛选出年龄大于25的People对象:
public class FunctionalInterfaceTest { private ListpeopleList = new ArrayList < > (); @Before public void init() { peopleList.add(new People("LuoTianyan", 23)); peopleList.add(new People("ff", 26)); peopleList.add(new People("Tony", 33)); } /** * 自定义函数式接口 */ @Test public void testUserDefined() { Listfilter = Filter.filter(peopleList, p - > ((People) p) .getAge() > 25); filter.forEach(System.out::println); /*People(name=ff, age=26) People(name=Tony, age=33)*/ } }
import lombok.*; @Getter @Setter @ToString @AllArgsConstructor @NoArgsConstructorpublic class People { private String name; private int age; }
JDK中已有的函数式接口
上面的自定义的函数式接口,返回boolean,其实在Java8中已经有该类型的接口,那就是Predicate。
Predicate
该接口定义了一个支持泛型的boolean test( T)的抽象方法,其函数描述符为 (T)->
boolean,现在我们就可以直接使用Predicate
在上面的Filter类中追加一个方法,修改这里形参为Predicate。
public staticListpredicate(Listlist, Predicate predicate) { if (CollectionUtils.isEmpty(list)) { return new ArrayList < > (0); } Listresult = new ArrayList < > (list.size()); for (int i = 0; i < list.size(); p = "" i++) { <= "" > T t = list.get(i); if (predicate.test(t)) { result.add(t); } } return result; }
获取Age>25的People对象,测试如下:
/** * Java8内置的函数式编程接口Predicate,返回boolean类型 */ @Test public void testPredicate() { Listpredicate = Filter.predicate(peopleList, p - > ((People) p) .getAge() > 25); predicate.forEach(System.out::println); }
Consumer
该接口定义了一个void accept(T)的抽象方法,其函数描述符为 (T) ->
void,如果你需要一个操作某一对象,但无需返回的的函数式接口,那么就可以使用Consumer
追加方法,形参为Consumer:
public staticvoid consumer(Listlist, Consumer consumer) { if (CollectionUtils.isEmpty(list)) { return; } Listresult = new ArrayList < > (list.size()); for (int i = 0; i < list.size(); p = "" i++) { <= "" > T t = list.get(i); consumer.accept(t); } }
下面实现修改所有Age为18,并且输出,测试如下:
/** * Java8内置的函数式编程接口Consumer,直接消费无返回值 */ @Test public void testConsumer() { // setAge操作不需要返回值 ConsumersetAgeConsumer = p - > ((People) p) .setAge(18); Filter.consumer(peopleList, setAgeConsumer); // 输出操作不需要返回值 Consumersout = p - > System.out.println((People) p); Filter.consumer(peopleList, sout); /*People(name=LuoTianyan, age=18) People(name=ff, age=18) People(name=Tony, age=18)*/ }
Supplier
既然有消费者接口(Consumer
追加方法,形参Supplier
public staticListlistFactory(int count, Suppliersupplier) { Listresult = new ArrayList < > (count); for (int i = 0; i < count; p = "" i++) { <= "" > T t = supplier.get(); result.add(t); } return result; }
下面生成count个对象,设置对象默认属性值:
/** * Java8内置的函数式编程接口supplier,无形参,返回对象 */ @Test public void testSupplier() { // 生成对象 SupplierpeopleSupplier = () - > new People("init", 18); Listpeople = Filter.listFactory(5, peopleSupplier); // 输出操作不需要返回值 Consumersout = p - > System.out.println((People) p); Filter.consumer(people, sout); /*People(name=init, age=18) People(name=init, age=18) People(name=init, age=18) People(name=init, age=18) People(name=init, age=18)*/ }
Function
该接口定义了一个 R
apply(T)类型的抽象函数,它接受一个泛型变量T,并返回一个泛型变量R,如果你需要将一个对象T映射成R,那么就可以使用Function
下面,我们将对象转化为String类型的例子
public staticListfunction(Listlist, Functionfunction) { if (CollectionUtils.isEmpty(list)) { return new ArrayList < > (0); } Listresult = new ArrayList < > (list.size()); for (int i = 0; i < list.size(); p = "" i++) { <= "" > T t = list.get(i); String apply = function.apply(t); result.add(apply); } return result; }
将People对象,转换为的字符串输出:
/** * Java8内置的函数式编程接口Function,接受形参T,转换为对象R */ @Test public void testFunction() { // 将People对象,转换为如下形式的字符串 Functionfunction = (People p) - > "name:" + p.getName() + " , age:" + p.getAge(); Liststrings = Filter.function(peopleList, function); // 输出操作不需要返回值 Consumersout = p - > System.out.println(p); Filter.consumer(strings, sout); /*name:LuoTianyan , age:23 name:ff , age:26 name:Tony , age:33*/ }
上面代码的优化
由于上面的people是list集合,可以直接利用stream的形式;
比如People对象转换成字符串
@Test public void testListStream() { Listcollect = peopleList.stream() .map(p - > p.getName() + p.getAge()) .collect(Collectors.toList()); collect.forEach(System.out::println); /*LuoTianyan23 ff26 Tony33*/ }
其实java函数式接口的作用就是提高编程效率,所以java函数式接口的使用我们一定要掌握!最后大家如果想要了解更多初识java知识,敬请关注奇Q工具网。
推荐阅读: