Java8中的Function、Supplier、Consumer、Predicate

109 阅读4分钟

说到java8的特性,就会离不开stream流式编程,而在流式编程里面,有几个类就要不得不说一下:Function、Supplier、Consumer、Predicate。接下来会逐一进行讲解使用。

Function

1.先说使用场景

Function 使用场景在stream中的map方法,在Stream类中可以看到方法

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

2.Function使用

Function意为函数,和数学中的函数也一样,有入参和出参,入参经过运算之后得到出参。共有4个方法apply,andThen,compose,identity。我们分别用代码形式进行对4个方法进行示例:
apply:

/**
 * 声明中有两个泛型Function<T, R>,T代表入参,R代表出参数
 */
public void functionApply(){
    //声明了一个入参是Integer,出参是string类型的函数
    Function<Integer,String> function = a -> "数字是:"+a;
    String result = function.apply(5);
    System.out.println(result);
};

andThen:

/**
 * default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
 *         Objects.requireNonNull(after);
 *         return (T t) -> after.apply(apply(t));
 * }
 * andThen可以将两个function合并成一个function并返回,同时可以通过实现上面看到,
 * 当前的function会优先执行,随后执行andThen后面的function
 * 同时先执行的参数会传递到后面
 */
public void functionAndThen(){
    //此处声明入参为int类型,出参为string类型的function1
    Function<Integer,String> function1 = a -> "数字是:"+a;
    //由于我们要在function1后要执行function2,function1的出参会给作为function2的入参,由于function1出参为string,所以声明为Function<String,String>
    Function<String,String> function2 = a -> "接收到的参数是:"+a;
    Function<Integer, String> function = function1.andThen(function2);
    String result = function.apply(5);
    System.out.println(result);
}

compost:

/**
 * default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
 *         Objects.requireNonNull(before);
 *         return (V v) -> apply(before.apply(v));
 * }
 * compose方法同样可以将两个function合并成一个并返回,同时可以通过实现可以看到,传入的function优先执行,
 * 所有执行当前的function,所以可以看到出入参位置有调整,before的出参作为当前function的入参
 *
 */
public void functionCompose(){
    //由于我们要在function1前要执行function2,function2的出参会给作为function1的入参,由于function1出参为string,所以声明为Function<String,String>
    Function<Integer,String> function1 =  a -> "接收到的参数是:"+a;;
    //此处声明入参为string类型,出参为int类型
    Function<String,Integer> function2  =a -> Integer.parseInt(a);
    Function<String, String> function = function1.compose(function2);
    String result = function.apply("5");
    System.out.println(result);
}

identity:

/**
 * identity:有一致,同一性的翻译。 方法为总返回当前本身
 * 使用场景:当使用stream遍历map时候,可以使用
 * Stream<String> stream = Stream.of("1", "22", "333");
 * Map<String, Integer> map = stream.collect(Collectors.toMap(Function.identity(), String::length))
 */
public void functionIdentity(){
    Function<String, String> identity = Function.identity();
    String result = identity.apply("数字5");
    System.out.println(result);
}

Supplier

1.先说使用场景

在Stream中有generate方法使用了Supplier方法作为入参,用于生产也给无限的流。

 public static<T> Stream<T> generate(Supplier<T> s) {
        Objects.requireNonNull(s);
        return StreamSupport.stream(
                new StreamSpliterators.InfiniteSupplyingSpliterator.OfRef<>(Long.MAX_VALUE, s), false);
    }

2.Supplier使用

Supplier翻译为供应商,可以理解为生产方,用于生产消息。共有一个方法:get,直接上示例:
get:

public void supplierGet(){
    // get方法声明泛型只有一个出参类型
    Supplier<String> supplier = () -> "hahahaha";
    String result = supplier.get();
    System.out.println(result);
}

Consumer

1.使用场景

stream中遍历数据,stream中的foreach方法,正是使用的这个,只是用来消费

void forEach(Consumer<? super T> action);

2Consumer使用

Consumer被意为消费者,与Supplier相反,只是用来消费消息,所以只接受入参,不需要出参,共有两个方法:accept,andThen
accept:

/**
 * accept只有一个入参,不会返回出参,泛型为入参的类型
 */
public void consumerAccept(){
    Consumer<Integer> consumer = a -> System.out.println("收到参数:"+ a);
    consumer.accept(123);
}

andThen:

/**
 *default Consumer<T> andThen(Consumer<? super T> after) {
 *         Objects.requireNonNull(after);
 *         return (T t) -> { accept(t); after.accept(t); };
 * }
 * andThen方法组合两个consumer,优先执行当前的consumer,后执行传入的consumer
 */
public void consumerAndThen(){
    Consumer<Integer> consumer1 = a -> System.out.println("consumer1收到参数:"+ a);
    Consumer<Integer> consumer2 = a -> System.out.println("consumer2收到参数:"+ a);
    Consumer<Integer> newConsumer = consumer1.andThen(consumer2);
    newConsumer.accept(123);
}

Predicate

1.使用场景:

同样在Stream中,用于过滤元素使用,可见filter方法中入参为Predicate

Stream<T> filter(Predicate<? super T> predicate);

2.使用方式

Predicate意为谓语,断言;用来进行匹配使用。共有5个方法,test,and,or,negate,isEqual
test:

/**
 * test方法用来匹配是否满足,用来判断结果
 */
public void predicateTest(){
    //仅有一个泛型为入参类型
    Predicate<String> predicate = a -> a.equals("aaa");
    boolean aaa = predicate.test("aaa");
    System.out.println(aaa);
}

and

/**
 * and方法可以进行组合两个Predicate,返回一个新的Predicate
 * 在实现逻辑上可以理解为 && 并且的关系
 */
public void predicateAnd(){
    Predicate<String> predicate1 = a -> a.equals("aaa");
    Predicate<String> predicate2 = a -> a.equals("aaaa");
    Predicate<String> newPredicate = predicate1.and(predicate2);
    boolean aaa = newPredicate.test("aaa");
    System.out.println(aaa);
}

or:

/**
 * or方法可以进行组合两个Predicate,返回一个新的Predicate
 * 在实现逻辑上可以理解为 || 或的关系
 */
public void predicateOr(){
    Predicate<String> predicate1 = a -> a.equals("aaa");
    Predicate<String> predicate2 = a -> a.equals("aaaa");
    Predicate<String> newPredicate = predicate1.or(predicate2);
    boolean aaa = newPredicate.test("aaa");
    System.out.println(aaa);
}

negate:

/**
 * Negate意为:否定;取消;失效,通过一个已有的Predicate创建一个新的Predicate
 * 在实现逻辑上可以理解为 ! 非的关系
 */
public void predicateNegate(){
    Predicate<String> predicate1 = a -> a.equals("aaa");
    Predicate<String> predicate2 = predicate1.negate();
    boolean result = predicate2.test("aaa");
    System.out.println(result);
}

isEqual

/**
 * isEqual 可以比较两个对象见是否一致,底层使用Object的equals方法
 */
public void predicateIsEqual(){
    //仅有一个泛型为入参类型
    Predicate<String> predicate1 = a -> a.equals("aaa");
    Predicate equal = Predicate.isEqual(predicate1);
    boolean aaa = equal.test(predicate1);
    System.out.println(aaa);
}