常用函数式接口
函数式接口 | 函数描述符 | 原始类型特化 |
---|---|---|
Predicate | T->boolean | IntPredicate,DoublePredicate,LongPredicate |
Consumer | T->void | IntConsumer,LongConsumer,DoubleConsumer |
Function<T, R> | T->R | IntFunction,IntToDoubleFunction,IntToLongFunction,LongFunction,LongToDoubleFunction,LongToIntFunction,DoubleFunction,DoubleToIntFunction,DoubleToLongFunction, ToIntFunction,ToLongFunction |
Supplier | ()->T | BooleanSupplier,IntSupplier,LongSupplier,DoubleSupplier |
UnaryOperator | T->T | IntUnaryOperator,LongUnaryOperator,DoubleUnaryOperator |
BinaryOperator | (T,T)->T | IntBinaryOperator,LongBinaryOperator,DoubleBinaryOperator |
BiPredicate<T, U> | (L,R)->boolean | |
BiConsumer<T, U> | (T,R)->void | ObjIntConsumer,ObjLongConsumer,ObjDoubleConsumer |
BiFunction<T, U, R> | (T,U)->R | ToIntBiFunction<T, U>,ToLongBiFunction<T, U>,ToDoubleBiFunction<T, U> |
Lambdas及函数式接口的例子
使用案例 | Lambda的例子 | 对应的函数式接口 |
---|---|---|
布尔表达式 | (List list) -> list.isEmpty() | Predicate<List> |
创建对象 | ()->new Apple(10) | Supplier |
消费一个对象 | (Apple a) -> System.out.println(a.getWeight()) | Consumer |
从一个对象中选择/提取 | (String s) -> s.length() | Function<Sring, Integer>或ToIntFunction |
合并两个值 | (int a, int b) -> a*b | IntBinaryOperator |
比较两个对象 | (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight()) | Comparator或BiFunction<Apple, Apple, Integer>或ToIntBiFunction<Apple, Apple> |
Predicate 断言型接口
Predicate接口中定义了一个名为test的抽象方法,它接受泛型T对象,并返回一个boolean。还有and/or等方法。
源码:
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
default Predicate<T> negate() {
return (t) -> !test(t);
}
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}
使用示例:
//定义一个对象product,代码省略
//private Long id;
//private Integer num;
//private Double price;
//private String name;
Product prod1 = new Product(1L, 1, new Double(15.5), "面包");
Product prod2 = new Product(2L, 2, new Double(20), "饼干");
Product prod3 = new Product(3L, 3, new Double(30), "月饼");
List<Product> prodList = Lists.newArrayList(prod1, prod2, prod3);
//定义一个filter方法
public static <T> List<T> filter(List<T> list, Predicate<T> p){
List<T> results = new ArrayList<>();
for(T s :list) {
if(p.test(s)) {
results.add(s);
}
}
return results;
}
//测试代码
Predicate<Product> pre = prod -> prod.getNum() > 1;
//and
//Predicate<Product> andpre = pre.and(prod -> prod.getNum() < 3);
//or和negate类似
List<Product> filterList = filter(prodList, pre);
filterList.forEach(item -> {
System.out.println(item.getNum());
});
//输出2 3
Consumer 消费型接口(void accept(T t))
Consumer定义了一个名叫accept的抽象方法,它接受泛型T的对象,没有返回(void)。如果需要访问类型T的对象,并对它执行某些操作,就可以使用这个接口。
源码:
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
比如上个例子中的forEach方法
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
Supplier:供给型接口
可以创建对象
源码:
@FunctionalInterface
public interface Supplier<T> {
T get();
}
示例:
Supplier<Apple> c1 = Apple::new;
Apple a1 = c1.get();
Supplier<Apple> c1 = () -> new Apple();
Apple a1 = c1.get();
Function<T, R> : 函数型接口
Function<T, R>接口定义了一个叫作apply的方法,它接受一个泛型T的对象,并返回一个泛型R的对象。
源码:
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
static <T> Function<T, T> identity() {
return t -> t;
}
}
示例:
public static <T, R> List<R> map(List<T> list, Function<T, R> f){
List<R> result = new ArrayList<>();
for(T s : list) {
result.add(f.apply(s));
}
return result;
}
List<Integer> numList = map(prodList, p -> p.getNum());
numList.forEach(item -> {
System.out.println(item);
});
// 1 2 3
andThen
我们使用g(f(x))来解释andThen,先计算f(x),然后再计算g()
Function<Integer, Integer> f = x -> x + 1;
Function<Integer, Integer> g = x -> x * 2;
Function<Integer, Integer> h = f.andThen(g);
System.out.println(h.apply(1));
// 输出4
compose
我们使用f(g(x))来解释compose,先计算g(x),然后再计算f()
Function<Integer, Integer> f = x -> x + 1;
Function<Integer, Integer> g = x -> x * 2;
Function<Integer, Integer> h = f.compose(g);
System.out.println(h.apply(1));
// 输出3
相关链接:
java8中map新增方法详解
java8中Stream的使用
java8中Collection新增方法详解
java8中Collectors的方法使用实例
java8中常用函数式接口
java8中的方法引用和构造函数引用
java8中的Collectors.groupingBy用法
java8中的Optional用法
java8中的日期和时间API