Consumer、Function、Predicate、Supplier
函数式接口,即有且仅有一个抽象方法的接口
1:Consumer< T> 接口
Consumer:代表了接受一个输入参数并且无返回的操作,相当于消费者。
consumer源码
package java.util.function;
import java.util.Objects;
@FunctionalInterface
public interface Consumer {
void accept(T t);
default Consumer andThen(Consumer super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
核心方法如下
1.void accept(T t);
对给定的参数T执行定义的操作
2.default Consumer andThen(Consumer super T> after)
对给定的参数T执行定义的操作然后再继续执行after定义的操作
accept(T t)
//1:定义Consumer要执行的操作,调用accept方法执行
Consumer consumer= i-> {
int a=i*3;
System.out.println(a);
};
consumer.accept(2);//程序输出6
//2:forEach中支持Consumer表达式,所以将表达式传入即可,默认会执行accept方法
List list = new ArrayList<>();
Consumer consumer1= i->{
list.add(i);
};
Stream.of("a","b","c").forEach(consumer1);
//可使用lambda表达式简写成下列方式
//Stream.of("a","b","c").forEach(i-> list.add(i));
System.out.println(list);//输出 [a, b, c]
default Consumer andThen(Consumer super T> after)
//1:先用i*3再调用i*4方法
Consumer consumer= i-> {
int a=i*3;
System.out.println(a);
};
Consumer after= i-> {
int a=i*4;
System.out.println(a);
};
consumer.andThen(after).accept(2);//程序先输出6,再输出8
与Consumer相关的接口
BiConsumer
代表了一个接受两个输入参数的操作,并且不返回任何结果
DoubleConsumer
处理一个double类型的参数,并且不返回任何结果
IntConsumer
处理一个int类型的参数,并且不返回任何结果
LongConsumer
处理一个long类型的参数,并且不返回任何结果
ObjDoubleConsumer< T>
接受一个object类型和一个double类型的输入参数,无返回值。
ObjIntConsumer< T>
接受一个object类型和一个int类型的输入参数,无返回值。
ObjLongConsumer< T>
接受一个object类型和一个long类型的输入参数,无返回值。
Consumer延申接口的demo
public class test {
public static void main(String[] args) {
User user=new User();
//BigConsumer的使用
BiConsumer bigConsumer=(o1,o2)-> user.temp=o1+o2;
bigConsumer.accept("hello ", "world");
System.out.println(user.getTemp());
Map map = new HashMap<>();
map.put("a", "a");
map.put("b", "b");
map.forEach((k, v) -> {
System.out.println(k);
System.out.println(v);
});
//DoubleConsumer
DoubleConsumer douConsumer=(i)-> System.out.println(i);
douConsumer.accept(1.22);
//ObjIntConsumer
ObjIntConsumer objIntConsumer=(o1,o2)-> user.intValue=o1.intValue+o2;
objIntConsumer.accept(user, 8);
}
}
@Data
class User{
int intValue=22;
Double doubleValue=2.2;
String temp;
}
执行结果:
hello world
1.22
30
2:Function
Function: 接受一个输入参数T,返回一个结果R。
Function源码
package java.util.function;
import java.util.Objects;
@FunctionalInterface
public interface Function {
R apply(T t);
default Function compose(Function super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
default Function andThen(Function super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
static Function identity() {
return t -> t;
}
}
核心方法:
R apply(T t)
输入参数T,处理后返回类型为R的对象
Function
先执行一次before的表达式,再执行apply方法
Function
与compose方法相反,先执行apply方法,再执行after的表达式
测试demo
//输入一个Integer参数,返回String类型
Function function=i-> String.valueOf(i);
System.out.println(function.apply(123)); //输出123
Function function1=i-> i*i;
Function function2=i-> i+1;
//求数字的平方
System.out.println(function1.apply(3));//输出9
//测试compose方法
System.out.println(function1.compose(function2).apply(2));//输出9 等价于function1.apply(function2.apply(2))
//测试compose方法
System.out.println(function1.andThen(function2).apply(2));//输出5 等价于function2.apply(function1.apply(2))
Function与Stream的使用
< R> Stream< R> map(Function super T, ? extends R> mapper);
List list=Arrays.asList(1,2,3,4);
list.stream().map(i -> i*2).forEach(System.out::print); //输出 2468
Function延申的接口
BiFunction
代表了一个接受T,U两个输入参数的方法,并且返回一个R结果
IntFunction< R>
接受一个int类型输入参数,返回一个结果 。
DoubleFunction< R>
代表接受一个double值参数的方法,并且返回结果
LongFunction< R>
接受一个long类型输入参数,返回一个结果。
DoubleToIntFunction
接受一个double类型输入,返回一个int类型结果。
DoubleToLongFunction
接受一个double类型输入,返回一个long类型结果
IntToDoubleFunction
接受一个int类型输入,返回一个double类型结果 。
IntToLongFunction
接受一个int类型输入,返回一个long类型结果。
LongToDoubleFunction
接受一个long类型输入,返回一个double类型结果.
LongToIntFunction
接受一个long类型输入,返回一个int类型结果。
ToDoubleBiFunction
接受两个输入参数,返回一个double类型结果
ToDoubleFunction< T>
接受一个输入参数,返回一个double类型结果
ToIntBiFunction
接受两个输入参数,返回一个int类型结果。
ToIntFunction< T>
接受一个输入参数,返回一个int类型结果。
ToLongBiFunction
接受两个输入参数,返回一个long类型结果。
ToLongFunction< T>
接受一个输入参数,返回一个long类型结果。
3:Predicate < T> 接口
Predicate 接口是一个函数式接口,它接受一个输入参数 T,返回一个布尔值结果。
predicte< T>源码
package java.util.function;
import java.util.Objects;
@FunctionalInterface
public interface Predicate {
boolean test(T t);
default Predicate and(Predicate super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
default Predicate negate() {
return (t) -> !test(t);
}
default Predicate or(Predicate super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
static Predicate isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
@SuppressWarnings("unchecked")
static Predicate not(Predicate super T> target) {
Objects.requireNonNull(target);
return (Predicate)target.negate();
}
}
核心方法
boolean test(T t)
判断参数T是否满足要求,返回boolean值
default Predicate< T> and(Predicate super T> other)
调用当前Predicate的test方法之后再去调用other的test方法,相当于进行两次判断
Predicate< T> negate()
对当前判断进行"!"操作,即取非操作,可理解为 ! 条件A
default Predicate< T> or(Predicate super T> other)
对当前判断进行"||"操作,即取或操作,可以理解为 条件A ||条件B
static < T> Predicate< T> isEqual(Object targetRef)
对当前操作进行"="操作,即取等操作,可以理解为 A == B
测试demo
//jdk8以前的写法
Predicate test=new Predicate() {
@Override
public boolean test(String s) {
return s.equals("aa");
}
};
//jdk8及之后的简写
Predicate predicate=(s)->s.equals("aa");
//测试test方法 满足条件A
System.out.println("测试test:"+predicate.test("bb"));//输出false
//测试negate方法 满足条件 !A
System.out.println("测试negate:"+predicate.negate().test("bb"));//输出true
//测试not方法 跟nagete一样的效果 满足条件 !A
System.out.println("测试not:"+Predicate.not(predicate).test("bb"));//输出true
//测试isEqual方法 跟equals()一样的效果 满足条件 a==b
System.out.println("测试isEqual:"+Predicate.isEqual("aa").test("bb"));//输出false
Predicate predicate1=(s)-> s>2;
//测试and方法,数字大于2且是奇数 满足条件 A && B
predicate1.and(s-> s%2==1);
System.out.println("测试and:"+predicate1.test(5));//输出true
//测试or方法 满足 A || B
System.out.println("测试or:"+predicate1.or(s-> s%2==1).test(1));//输出true
执行结果:
测试test:false
测试negate:true
测试not:true
测试isEqual:false
测试and:true
测试or:true
Predicate与Stream的组合使用
Stream< T> filter(Predicate super T> predicate);
filter接收一个Predicate对象
demo
List list = Arrays.asList(1, 2, 3, 4, 5, 6);
//输出奇数 list.stream(), 表示将List作为流进行处理, filter()方法接收一个Predicate, toArray是将流转换成数组
Object[] result = list.stream().filter(t -> t % 2 == 1).toArray();
System.out.println("奇数:" + Arrays.toString(result));
//测试Predicate的and方法, 返回list中大于2小于5的集合
Predicate predicate = t -> t > 2;
predicate = predicate.and(t -> t < 5);
List list1= list.stream().filter(predicate).collect(Collectors.toList());
System.out.println("大于2小于5的集合:" + list1);
//测试Predicate的or方法, 返回list中小于2或大于4的集合
predicate = t -> t < 2;
predicate = predicate.or(t -> t > 4);
list1 = list.stream().filter(predicate).collect(Collectors.toList());
System.out.println("小于2或大于4:" + list1);
// 5. 测试Predicate的negate方法, 返回list中大于等于2,小于等于4的集合
list1 = list.stream().filter(predicate.negate()).collect(Collectors.toList());
System.out.println("大于等于2小徐等于4的集合:" +list1);
Predicate延申的接口
BiPredicate
代表了一个T,U两个参数的boolean值方法
DoublePredicate
代表一个拥有double值参数的boolean值方法
IntPredicate
:接受一个int输入参数,返回一个布尔值的结果。
LongPredicate
R接受一个long输入参数,返回一个布尔值类型结果。
4:Supplier< T>
supplier:供给者,传入一个泛型T,调用get方法,返回一个泛型T
Supplier< T>源码
package java.util.function;
@FunctionalInterface
public interface Supplier {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
测试demo
public class test {
public static void main(String[] args) {
Supplier supplier = String::new;
System.out.println(supplier.get());//""
Supplier suppUser = User::new;
User user = suppUser.get();
user.setName("张三");
System.out.println(user.getName());//dd
//每次调用get方法,会重新调用一次构造方法,相当于new了一次
suppUser.get();
}
}
@Data
class User{
String name;
int age;
}
Supplier相关的接口
BooleanSupplier
代表了boolean值结果的提供方
IntSupplier
无参数,返回一个int类型结果。
LongSupplier
无参数,返回一个结果long类型的值。
DoubleSupplier
代表一个double值结构的提供方