【JAVA8新特性】Supplier接口、Consumer接口、Function接口、Predicate接口

前言

这四个类都属性java.util.function包下比较常见的类,在日常的工作中大多数处理lambda的展现形式,不是明显可见的。

Supplier接口

/**
 * Represents a supplier of results.
 *
 * <p>There is no requirement that a new or distinct result be returned each
 * time the supplier is invoked.
 *
 * <p>This is a <a href="package-summary.html">functional interface</a>
 * whose functional method is {@link #get()}.
 *
 * @param <T> the type of results supplied by this supplier
 *
 * @since 1.8
 */
@FunctionalInterface
public interface Supplier<T> {

    /**
     * Gets a result.
     *
     * @return a result
     */
    T get();
}

官方解释:表示结果的提供者。

有点抽象,其实就是一个存储指定泛型的容器,是一个供给型的接口,其中的get方法就是用来获取存储的数据的。常在通用工具类的设计中会用到。

Supplier不需要入参,需要返参

	@Test
    public void SupplierTest() {

        // 写法1
        Supplier<String> dataA = new Supplier<String>() {
            @Override
            public String get() {
                return "存储的数据A";
            }
        };
        // 写法2 lambda表达式
        Supplier<String> dataB = () -> "存储的数据B";

        System.out.println(dataA.get());
        System.out.println(dataB.get());
    }

控制台

Connected to the target VM, address: '127.0.0.1:52477', transport: 'socket'
存储的数据A
存储的数据B
Disconnected from the target VM, address: '127.0.0.1:52477', transport: 'socket'

Consumer接口

/**
 * Represents an operation that accepts a single input argument and returns no
 * result. Unlike most other functional interfaces, {@code Consumer} is expected
 * to operate via side-effects.
 *
 * <p>This is a <a href="package-summary.html">functional interface</a>
 * whose functional method is {@link #accept(Object)}.
 *
 * @param <T> the type of the input to the operation
 *
 * @since 1.8
 */
@FunctionalInterface
public interface Consumer<T> {

    /**
     * Performs this operation on the given argument.
     *
     * @param t the input argument
     */
    void accept(T t);
    
	// 	其他方法暂省略
}

官方解释:表示接受单个输入参数且不返回结果的操作。

Consumer是一个消费型接口,对传入的数据进行处理,然后输出。

Stream流中的foreach中就是需要传入这个接口

Consumer需要入参,没有返参

    @Test
    public void ConsumerTest() {

        Consumer<String> consumer = new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println("我需要处理数据:" + s);
            }
        };
        Stream<String> stream = Stream.of("A", "B", "C", "D", "E");
        stream.forEach(consumer);
    }

控制台

Connected to the target VM, address: '127.0.0.1:57993', transport: 'socket'
我需要处理数据:A
我需要处理数据:B
我需要处理数据:C
我需要处理数据:D
我需要处理数据:E
Disconnected from the target VM, address: '127.0.0.1:57993', transport: 'socket'

Function接口


/**
 * Represents a function that accepts one argument and produces a result.
 *
 * <p>This is a <a href="package-summary.html">functional interface</a>
 * whose functional method is {@link #apply(Object)}.
 *
 * @param <T> the type of the input to the function
 * @param <R> the type of the result of the function
 *
 * @since 1.8
 */
@FunctionalInterface
public interface Function<T, R> {

    /**
     * Applies this function to the given argument.
     *
     * @param t the function argument
     * @return the function result
     */
    R apply(T t);

	// 	其他方法暂省略
}

官方解释:表示接受一个参数并产生一个结果的函数。

Function 接口是一个功能型接口,它的一个作用就是转换作用,将输入数据转换成另一种形式的输出数据。比如工作中用到的将数据库中查询出来的PO类型转化为VO或者DTO,就可以写一个公共的转化工具类,传入对应的Class类。

Stream流中的map中就是需要传入这个接口

	@Test
    public void FunctionTest() {

        Function<String, Integer> function = new Function<String, Integer>() {
            @Override
            public Integer apply(String s) {
                return s.hashCode();
            }
        };

        Stream<String> stream = Stream.of("A", "B", "C", "D", "E");
        stream.map(function).forEach(System.out::println);
    }

控制台

Connected to the target VM, address: '127.0.0.1:58095', transport: 'socket'
65
66
67
68
69
Disconnected from the target VM, address: '127.0.0.1:58095', transport: 'socket'

Function接口有入参,也有回参

Predicate接口


/**
 * Represents a predicate (boolean-valued function) of one argument.
 *
 * <p>This is a <a href="package-summary.html">functional interface</a>
 * whose functional method is {@link #test(Object)}.
 *
 * @param <T> the type of the input to the predicate
 *
 * @since 1.8
 */
@FunctionalInterface
public interface Predicate<T> {

    /**
     * Evaluates this predicate on the given argument.
     *
     * @param t the input argument
     * @return {@code true} if the input argument matches the predicate,
     * otherwise {@code false}
     */
    boolean test(T t);

	// 	其他方法暂省略
}

官方解释:表示一个参数的谓词(布尔值函数)。

Predicate 接口是一个谓词型接口,其实,这个就是一个类似于 bool 类型的判断的接口,实现其中的test方法进行判断。

Stream流中的anyMatch中就是需要传入这个接口

 	@Test
    public void PredicateTest() {

        Predicate<String> predicate = new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.length() > 2;
            }
        };
        Stream<String> stream = Stream.of("AAA", "B", "C", "D", "E");
        System.out.println(stream.anyMatch(predicate));

    }

控制台

Connected to the target VM, address: '127.0.0.1:55164', transport: 'socket'
true
Disconnected from the target VM, address: '127.0.0.1:55164', transport: 'socket'

补充

发现Supplier接口、Consumer接口、Function接口、Predicate接口这四个都被@FunctionalInterface注解修饰。


/**
 * An informative annotation type used to indicate that an interface
 * type declaration is intended to be a <i>functional interface</i> as
 * defined by the Java Language Specification.
 *
 * Conceptually, a functional interface has exactly one abstract
 * method.  Since {@linkplain java.lang.reflect.Method#isDefault()
 * default methods} have an implementation, they are not abstract.  If
 * an interface declares an abstract method overriding one of the
 * public methods of {@code java.lang.Object}, that also does
 * <em>not</em> count toward the interface's abstract method count
 * since any implementation of the interface will have an
 * implementation from {@code java.lang.Object} or elsewhere.
 *
 * <p>Note that instances of functional interfaces can be created with
 * lambda expressions, method references, or constructor references.
 *
 * <p>If a type is annotated with this annotation type, compilers are
 * required to generate an error message unless:
 *
 * <ul>
 * <li> The type is an interface type and not an annotation type, enum, or class.
 * <li> The annotated type satisfies the requirements of a functional interface.
 * </ul>
 *
 * <p>However, the compiler will treat any interface meeting the
 * definition of a functional interface as a functional interface
 * regardless of whether or not a {@code FunctionalInterface}
 * annotation is present on the interface declaration.
 *
 * @jls 4.3.2. The Class Object
 * @jls 9.8 Functional Interfaces
 * @jls 9.4.3 Interface Method Body
 * @since 1.8
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}

1、该注解只能标记在"有且仅有一个抽象方法"的接口上。

2、JDK8接口中的静态方法和默认方法,都不算是抽象方法。

3、接口默认继承java.lang.Object,所以如果接口显示声明覆盖了Object中方法,那么也不算抽象方法。

4、该注解不是必须的,如果一个接口符合"函数式接口"定义,那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值