流继承关系, DoubbleStream IntStream LongStream是针对于基本类型double int long,其他基本类型没有对应的流
1. 谓词接口 接受一个T 返回boolean
有Predicate<T> IntPredicate LongPredicate DoublePredicate
Predicate 除了有谓词的意思,还有断定,断言的意思,它的作用就是声明一个或组合的条件,满足为true,不满足为false
看接口中定义的方法, 接口方法中有一个test接口需要我们实现,其他都是默认方法,包括逻辑与,做逻辑非操作,逻辑或。还有一个非基本类型(仅指int long daouble)Predicate没有的方法判断两个对象是否相同
@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);
}
}
Predicate接口
DoublePredicate接口 DoublePredicate IntPredicate LongPredicate与Predicate没有继承关系
简单使用,定义一组过滤条件,然后取反,将数组转换成流
IntPredicate p =((IntPredicate) x->x > 10).and(x -> x < 20).or(x -> x == 30).negate();
Arrays.stream(new int[]{40, 30, 19, 5}).filter(p).forEach(System.out::println);
---output---
40
5
2. 单元操作接口 接受一个T类型参数 返回T类型对象
单元操作接口有UnaryOperator LongUnaryOperator IntUnaryOperator DoubleUnaryOperator
先看一下UnaryOperator是怎样的结构
@FunctionalInterface
public interface UnaryOperator<T> extends Function<T, T> {
static <T> UnaryOperator<T> identity() {
return t -> t;
}
}
我们看到只有一个静态方法(在Java8中是允许存在实现的静态方法的),没有看到需要实现的接口方法,但是它继承了Function<T, T>这个单元函数接口,看一下这个单元函数接口的类结构如下图:
我们补全从父类继承的接口方法
@FunctionalInterface
public interface UnaryOperator<T> extends Function<T, T> {
T apply(T t);
//这个函数的功能是先执行 before 这个表达式的操作,再执行apply
default <V> Function<V, T> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
//这个函数的功能是先执行apply,再执行 before 这个表达式的操作
default <V> Function<T, V> andThen(Function<? super T, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
static <T> UnaryOperator<T> identity() {
return t -> t;
}
}
然后我们在看IntUnaryOperator操作接口
@FunctionalInterface
public interface IntUnaryOperator {
int applyAsInt(int operand);
default IntUnaryOperator compose(IntUnaryOperator before) {
Objects.requireNonNull(before);
return (int v) -> applyAsInt(before.applyAsInt(v));
}
default IntUnaryOperator andThen(IntUnaryOperator after) {
Objects.requireNonNull(after);
return (int t) -> after.applyAsInt(applyAsInt(t));
}
static IntUnaryOperator identity() {
return t -> t;
}
}
发现这个接口并没有和UnaryOperator接口一样继承Function<T,R>单元函数接口,作者认为UnaryOperator是一个特殊的单元函数接口
简单使用一下,先+2 在+1 然后×3
IntUnaryOperator u1 = ((IntUnaryOperator)x -> x+1).compose(x -> x+2).andThen(x -> x*3);
Arrays.stream(new int[]{40, 30, 19, 5}).map(u1).forEach(System.out::println);
--output--
129
99
66
24
3. 二元操作接口 接受两个T参数 返回T类型对象
有BinaryOperator LongBinaryOperator IntBinaryOperator DoubleOperator
同一元操作接口,二元操作接口继承了二元函数接口
@FunctionalInterface
public interface BinaryOperator<T> extends BiFunction<T,T,T> {
//补全
int apply(int t1, int t2)
//补全 先执行apply 在执行after操作
default <V> BiFunction<T, T, V> andThen(Function<? super T, ? extends V> after) {
Objects.requireNonNull(after);
return (T t, T t1) -> after.apply(apply(t, t1));
}
//找最大值
public static <T> BinaryOperator<T> minBy(Comparator<? super T> comparator) {
Objects.requireNonNull(comparator);
return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
}
//找最小值
public static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) {
Objects.requireNonNull(comparator);
return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
}
}
而IntBinaryOperator只有一个方法
@FunctionalInterface
public interface IntBinaryOperator {
int applyAsInt(int left, int right);
}
二元操作接口可以用在reduce聚合操作上
Arrays.stream(new int[]{40, 30, 19, 5}).reduce((x, y) -> {
System.out.println("(" + x + "," + y + ")");
return x + y;
}).ifPresent(System.out::println);
--output--
(40,30)
(70,19)
(89,5)
94
4. 单元函数 Function<T,R> 接收一个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;
}
}
这个函数的功能和前面介绍的单元操作接口一样,唯一的区别是单元函数关心函数的返回值,可以将T->R
简单使用一下
IntFunction<String> i = x -> x + "intToStringFunction";
Arrays.stream(new int[]{40, 30, 19, 5}).mapToObj(i).forEach(System.out::println);
Function<Integer, String> its = x -> x + "function";
System.out.println(its.apply(1));
--output--
40intToStringFunction
30intToStringFunction
19intToStringFunction
5intToStringFunction
1function
除了Function, IntFunction, DoubleFunction, LongFunction,还提供了int long double互相转换的Function,例如IntToDoubleFunction,IntToLongFunction等单元函数接口,如果基本类型只明确了接受参数类型则会使用IntFunction, DoubleFunction, LongFunction,如果基本类型接受参数和返回类型都明确则会使用互转的函数接口。
5. 二元函数接口 接受两个参数T,U类型,返回R类型对象
@FunctionalInterface
public interface BiFunction<T, U, R> {
R apply(T t, U u);
default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t, U u) -> after.apply(apply(t, u));
}
}
简单使用一下
BiFunction<Integer, String, String> b = (x,y)->"(" + x + "," + y + ")";
System.out.println(b.apply(1, "one"));
--output--
(1,one)
除了BiFunction还有ToDoubleBiFunction ToLongBiFunction ToIntBiFunction确定返回类型的接口
6.消费者接口,接受T 返回void
@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); };
}
}
简单使用一下
Arrays.stream(new int[]{40, 30, 19, 5}).forEach(System.out::println);
除了Consumer<T> 还有IntConsumer DoubleConsumer LongConsumer
7. 二元消费者接口,接受T,U 返回void BiConsumer<T,U>
@FunctionalInterface
public interface BiConsumer<T, U> {
void accept(T t, U u);
default BiConsumer<T, U> andThen(BiConsumer<? super T, ? super U> after) {
Objects.requireNonNull(after);
return (l, r) -> {
accept(l, r);
after.accept(l, r);
};
}
}
简单使用一下
BiConsumer<Integer, String> bc = (x, y) -> System.out.println("(" + x + "," + y + ")");
bc.accept(1,"2");
8. 工厂接口
@FunctionalInterface
public interface Supplier<T> {
T get();
}
简单使用一下
Arrays.stream(new int[]{40, 30, 19, 5}).filter(x->x>20).collect(ArrayList::new, ArrayList::add, ArrayList::addAll).forEach(System.out::println);
除了Supplier<T> 还有IntSupplier BooleanSupplier DoubleSupplier LongSupplier