探索Java8:(五)Supplier和Consumer接口的使用

探索Java8:(五)Supplier和Consumer接口的使用Supplier是函数式编程的另一个接口,与Function、Predicate接口类似,区别在于Supplier不接收任何参数,只返回结果。Supplier的基本使用@FunctionalInterfacepublicinterfaceSupplier<T>{/***

大家好,欢迎来到IT知识分享网。

Supplier是函数式编程的另一个接口,与Function、Predicate接口类似,区别在于Supplier不接收任何参数,只返回结果。

Supplier的基本使用

@FunctionalInterface
public interface Supplier<T> {

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

使用Supplier也很简单,与Function接口一样,Supplier使用lambda表达式和方法引用来实例化。

public class SupplierTest {
  public static void main(String[] args) {
     Supplier<String> supplier1 = () ->10; 
     System.out.println(supplier1.get());

     LocalDateTime now = LocalDateTime.now();
     Supplier<String> supplier2 =()->now.toString();
     //也可以使用Supplier<String> supplier2 = now::toString
     System.out.println(supplier2.get());     
  }
} 

指定类型的Supplier

除了Supplie以外,Java8中还提供了BooleanSupplier, IntSupplier, LongSupplier, DoubleSupplier。以LongSupplier为例

@FunctionalInterface
public interface LongSupplier {

    /**
     * Gets a result.
     *
     * @return a result
     */
    long getAsLong();
}

通过源码我们可以看到,LongSupplier相当于是一个指定了返回参数类型的Supplier。建议这种带类型的函数式接口可以结合起来看,可以同时看下LongFunction、LongConsumer、LongPredicate。

public class LongSupplierTest {
  public static void main(String[] args) {
     LongSupplier supplier1 = () ->1000L; 
     System.out.println(supplier1.getAsLong());
  }
} 

自定义Supplier

我们也可以使用@FunctionalInterface 注解来自定义一个Supplier类。

import java.util.Random;

@FunctionalInterface
interface UserSupplier {
    User getUser();
}
class User{
   private String username;
   private String password;
   public User(){
      this.usename="test";
      this.password="test";
   }
}
public class CustomSupplierDemo {
  public static void main(String[] args) {
     UserSupplier s1=User::new;
     System.out.println(s1.getUser());
  }
} 

Consumer的基本使用

@FunctionalInterface
public interface Consumer<T> {

    /**
     * Performs this operation on the given argument.
     *
     * @param t the input argument
     */
    void accept(T t);

    /**
     * Returns a composed {@code Consumer} that performs, in sequence, this
     * operation followed by the {@code after} operation. If performing either
     * operation throws an exception, it is relayed to the caller of the
     * composed operation.  If performing this operation throws an exception,
     * the {@code after} operation will not be performed.
     *
     * @param after the operation to perform after this operation
     * @return a composed {@code Consumer} that performs in sequence this
     * operation followed by the {@code after} operation
     * @throws NullPointerException if {@code after} is null
     */
    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

Consumer和Supplier正好相反,Consumer接收一个参数,但不返回任何结果。可以把Consumer看成是消费者,Supplier看成是生产者。Consumer支持复合操作,可以使用andThen()来连接其他的Consumer完成对同一参数的多次消费。注意:Consumer不返回结果,因此复合消费其实是对传入参数的多次消费,并改变上一次消费的参数。这点要与Function有所区别。

我们举个例子来说明一下:

public class ConsumerTest {
  public static void main(String[] args) {
     Supplier<String> supplier2 =()->"Hello World!";
     Consumer<String> consumer1=c-> System.out.println(c.toLowerCase());
     Consumer<String> consumer2=c-> System.out.println(c.toUpperCase());
     consumer1.accept(s1.get());
     //多次消费操作
     consumer1.andThen(consumer2).accept(s1.get());

  }
} 

hello world!
hello world!
HELLO WORLD!

使用场景

Supplier比较常用的场景是提供一个返回结果。比如从HTTP请求中获取一个值,这个操作可以用Supplier包装起来。虽然Supplier可以返回静态的字符串或者其他对象,但实际开发中这样的业务逻辑不如直接写一个方法进行返回来的简单明了。Supplier真正的用武之地是对一个复杂操作返回结果进行包装。

Consumer的常用场景是对已有数据的处理,比如创建一个对象之后发送到kafka、redis、写入数据库等。
总之,函数式编程应该用在抽象层次高、复用多的场景,而不是单纯业务逻辑的简单使用(反而影响代码的可阅读性)。找到具体场景中的最佳实践才能发挥函数式编程最大优点。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/29138.html

(0)
上一篇 2023-09-28 17:45
下一篇 2023-09-28 18:45

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信