说到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);
}