java培训
搜索分类

java函数式接口的应用场景是什么?java函数式接口的应用场景

赋能网 2023-05-09 64

函数式接口就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。函数式接口可以被隐式转换为 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);
        
    }
}
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对象,测试如下:

@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,并且输出,测试如下:

@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);
    
}

Supplier接口

既然有消费者接口(Consumer),那就要有生产者接口(Supplier),该接口定义了一个 T get() 的抽象方法,其函数描述符为 () -> T,如果不接受入参,直接为我们生产一个指定的结果,那么就可以用Supplier

追加方法,形参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个对象,设置对象默认属性值:

@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);
    
}

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对象,转换为的字符串输出:

@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);
    
}

上面代码的优化

由于上面的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);
    
}

其实java函数式接口的作用就是提高编程效率,所以java函数式接口的使用我们一定要掌握!最后大家如果想要了解更多初识java知识,敬请关注赋能网。


发表评论
0评