在jdk8中为了简单对象的创建工作,以及集合的相关操作,分别新增了lambda表达式和stream流式操作,本文就起来看下。
可以认为是一种匿名函数,格式如下:
完整格式:
(parameters) -> {statements;}
如果是statement只有一行则可以省略{}:
(parameters) -> statements
如下简单的只有一个表达式例子:
1,没有参数,直接返回5
() -> 5
2,接受一个数字类型参数,返回其2倍的值
x -> 2*x
3,接收两个参数,返回他们的差值
(x, y) -> x-y
4,接收两个int类型整数,返回他们的和
(int x, int y) -> x+y
5,接收一个string对象,并在控制台打印,不返回任何值
(String s) -> System.out.println(s)
判断真假的函数式接口,源码如下:
@FunctionalInterface // 函数是接口注解,仅仅是个标记而已,没有该注解也无所谓,有更明确
public interface Predicate<T> {
// 基于给定的值t,返回真假
boolean test(T t);
// &短路操作,返回两个predicate的&结果,如果想要n个&的话,多次调用and即可
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);
}
// 判断是否和目标对象相等的Predicate
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}
接下来看下实例。
Predicate<Integer> p1 = (t) -> { // 这里是test方法的方法体
t = t * 2;
return t > 100;
};
System.out.println(p1.test(99));
运行:
true
Predicate<Integer> p1 = (t) -> { // 这里是test方法的方法体
t = t * 2;
return t > 100;
};
// System.out.println(p1.test(99));
Predicate<Integer> p2 = (t) -> { // 这里是test方法的方法体
t = t / 2;
return t > 99;
};
Predicate<Integer> p3 = p1.and(p2);
/*
相当于如下代码:
{ // 这里是test方法的方法体
t = t * 2;
return t > 100;
} && { // 这里是test方法的方法体
t = t / 2;
return t > 99;
}
*/
System.out.println(p3.test(600));
多次and:
Predicate<Integer> p1 = (t) -> { // 这里是test方法的方法体
t = t * 2;
return t > 100;
};
// System.out.println(p1.test(99));
Predicate<Integer> p2 = (t) -> { // 这里是test方法的方法体
t = t / 2;
return t > 99;
};
Predicate<Integer> p2_1 = (t) -> { // 这里是test方法的方法体
t = t / 2;
return t > 999;
};
Predicate<Integer> p3 = p1.and(p2).and(p2_1);
System.out.println(p3.test(600));
Predicate<Integer> p4 = (t) -> { // 这里是test方法的方法体
t = t / 2;
return t > 999;
};
Predicate<Integer> negate = p4.negate();
System.out.println(negate.test(888));
运行:
true
Process finished with exit code 0
Predicate<Integer> p4 = (t) -> { // 这里是test方法的方法体
t = t / 2;
return t > 999;
};
Predicate<Integer> p4_1 = (t) -> { // 这里是test方法的方法体
t = t * 2;
return t > 688;
};
Predicate<Integer> or = p4.or(p4_1);
System.out.println(or.test(100));
运行:
false
Process finished with exit code 0
对接收一个参数,并根据该参数返回一个结果操作的抽象接口,如下:
@FunctionalInterface
public interface Function<T, R> {
// 根据入参t执行逻辑,并返回值R
R apply(T t);
// 组合两个Function,使用第一个Function apply的返回值,作为第二个Function的入参,再apply
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
// 同compose但是2个Functin apply的顺序相反
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
// 返回一个永远直接返回入参的Function
static <T> Function<T, T> identity() {
return t -> t;
}
}
看下例子。
Function<String, String> f1 = (v) -> {
return v + "___===";
};
System.out.println(f1.apply("张三"));
运行:
张三___===
Process finished with exit code 0
Function<String, String> f1 = (v) -> {
return v + "A";
};
// System.out.println(f1.apply("张三"));
Function<String, String> f2 = (v) -> {
return v + "B";
};
Function<String, String> compose = f1.compose(f2);
System.out.println(compose.apply("张三"));
运行:
张三BA
Process finished with exit code 0
多个compose:
Function<String, String> f1 = (v) -> {
return v + "A";
};
// System.out.println(f1.apply("张三"));
Function<String, String> f2 = (v) -> {
return v + "B";
};
Function<String, String> f3 = (v) -> {
return v + "C";
};
Function<String, String> compose = f1.compose(f2).compose(f3);
System.out.println(compose.apply("张三"));
运行:
张三CBA
Process finished with exit code 0
Function<String, String> f1 = (v) -> {
return v + "A";
};
// System.out.println(f1.apply("张三"));
Function<String, String> f2 = (v) -> {
return v + "B";
};
Function<String, String> f3 = (v) -> {
return v + "C";
};
Function<String, String> compose = f1.andThen(f2).andThen(f3);
System.out.println(compose.apply("张三"));
运行:
张三ABC
Process finished with exit code 0
Function<String, String> f1 = Function.identity();
System.out.println(f1.apply("照镜子!!!"));
运行:
照镜子!!!
Process finished with exit code 0
对只接收一个入参,并对该参数执行操作,但是不需要返回值场景的抽象,源码如下:
@FunctionalInterface
public interface Consumer<T> {
// 对给定的入参t执行操作,但不需要返回值
void accept(T t);
// 返回 一次执行两个Consumer的accept 的Consumer
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
看下例子。
Consumer<String> c1 = (v) -> {
System.out.println("执行业务操作了。。。" + v);
};
c1.accept("follow your heart!!!");
运行:
执行业务操作了。。。follow your heart!!!
Process finished with exit code 0
Consumer<String> c1 = (v) -> {
System.out.println("执行业务操作了A" + v);
};
Consumer<String> c2 = (v) -> {
System.out.println("执行业务操作了B" + v);
};
c1.andThen(c2).accept("lab");
运行:
执行业务操作了Alab
执行业务操作了Blab
Process finished with exit code 0
对于不需要任何的入参,根据特定外部条件返回一个值场景的抽象,比如返回当前的时间戳,源码如下:
@FunctionalInterface
public interface Supplier<T> {
// 获取特定业务场景下的某个结果
T get();
}
例子:
Supplier<Long> supplier = () -> {
return System.currentTimeMillis();
};
System.out.println(supplier.get());
运行:
1688636413386
Process finished with exit code 0
代码:
// 泛型 T 必须是 Serializable&Comparable&Collection 必须是这三个接口的实现类
public class LambdaDemo<T extends Serializable&Comparable&Collection> {
public static void main(String args[]){
LambdaDemo demo = new LambdaDemo();
// Java 8以前的写法,当然现在也可以这样写,只是相对比较麻烦
MathOperation op2 = new MathOperation<Integer>() {
@Override
public Integer operation(int a, int b) {
return a+b;
}
};
// 参数不写数据类型,直接返回1,生意省略{}和return,相当于MathOperation op1 = (int a, int b) -> { return 1; };
MathOperation op1 = (a, b) -> 1;
// 参数声明类型,将两个入参之和作为结果返回,单语句,省略{}和return,相当于MathOperation addition = (int a, int b) -> {return a + b;};
MathOperation addition = (int a, int b) -> a + b;
// 参数声明类型,将两个入参之差作为结果返回,单语句,省略{}和return,相当于MathOperation addition = (int a, int b) -> {return a - b;};
MathOperation subtraction = (int a, int b) -> a - b ;
// 大括号中的返回语句
MathOperation multiplication = (int a, int b) -> {
//int c = 1000;
return a * b;// + c;
};
// 没有大括号及返回语句
MathOperation division = (int a, int b) -> a / b;
System.out.println("10 + 5 = " + demo.operate(10, 5, addition));
System.out.println("10 - 5 = " + demo.operate(10, 5, subtraction));
System.out.println("10 x 5 = " + demo.operate(10, 5, multiplication));
System.out.println("10 / 5 = " + demo.operate(10, 5, division));
System.out.println("10 ^ 5 = " + demo.operate(10, 5, (a, b) -> Math.pow(a,b)));
// 无参数,只有一个表达式,可以省略{},相当于Runnable task = () -> { System.out.println(1111); };
Runnable task = () -> System.out.println(1111);
// 不用括号
GreetingService greetService1 = message ->
System.out.println("Hello " + message);
// 用括号
GreetingService greetService2 = (message) -> {
System.out.println(message);
};
// 只有一个表达式并且调用的out的方法,可以通过::简写,并且省略参数声明和{},完整写法:GreetingService greetService3 = (message) -> { System.out.println(message); };
GreetingService greetService3 = System.out::println;
// 循环+3输出
Arrays.asList(1,2,3).forEach(x -> System.out.println(x+3));
// 循环调用LambdaDemo.println静态方法
Arrays.asList(1,2,3).forEach( LambdaDemo::println );
greetService1.sayMessage("kimmking");
greetService2.sayMessage("Java");
greetService3.sayMessage("CuiCuilaoshi");
}
private static void println(int x) {
System.out.println(x+3);
}
@FunctionalInterface
interface MathOperation<T> {
T operation(int a, int b); // 返回类型+函数名+参数类型的列表
}
interface GreetingService {
void sayMessage(String message);
}
private <T> T operate(int a, int b, MathOperation<T> mathOperation){
return mathOperation.operation(a, b);
}
}
运行:
10 + 5 = 15
10 - 5 = 5
10 x 5 = 50
10 / 5 = 2
10 ^ 5 = 100000.0
4
5
6
4
5
6
Hello kimmking
Java
CuiCuilaoshi
Process finished with exit code 0
流是来自数据源的元素队列,并支持以链式的方式进行聚合操作的抽象定义。
数据源:可以是集合,数组,I/O等
元素:单个数据
聚合操作:map,reduce,sort,limit等
stream的操作分为两类,分别是中间操作和终止操作,中间操作就是返回的依然是流,还可以继续执行其他的中间操作,终止操作是获取了最终的一个结果。
中间操作就是返回的依然是流,还可以继续执行其他的中间操作,主要包括如下的操作:
选择与过滤
1:filter(Predicate p) 排除元素
2:distinct() 通过元素的hashCode和equals()排除元素
3:limit(long maxSize) 截断流,使其元素不超过给定数量
4:skip(long n) 跳过元素,返回一个跳过了前n个元素的流,若流中元素不足n个,则返回一个空流
映射
1:map(Function f) 转换元素的值到另一个值
2:mapToDouble(ToDoubleFunction f) 将每个元素转换为Double,并返回DoubleStream
3:mapToInt(ToIntFunction f) 将每个元素转换为int,并返回IntStream
4:mapToLong(ToLongFunction f) 将每个元素转换为long,并返回LongStream
5:flatMap(Function f) 平铺为一个流,即如果中间的是集合,则展开
排序
1:sorted() 产生一个新流,按照自然顺序排序
2:sorted(Comparator comp) 产生一个新流,其中按照比较器的顺序排序
终止操作是获取了最终的一个结果,主要包括如下操作:
查找与匹配
1:allMatch(Predicate super T> predicate) 是否所有元素都会返回true
2:anyMatch(Predicate super T> predicate) 至少一个元素返回true
3:noneMatch(Predicate super T> predicate) 所有元素都返回fasle,即都不匹配
4:findFirst() 返回第一个元素,注意返回的是Option,避免NPE
5:findAny() 返回随机的一个元素,注意返回的是Option,避免NPE
6:count() 获取元素的总数
7:max() 获取最大值
8:min() 获取最小值
规约
reduce 需要初始值
收集collect
collect(Collections.toList()) 转换为List集合
collect(Collections.toSet()) 转换为Set集合
collect(toCollection(Supplier collectionFactory)) 转换为集合,泛型C确定哪种集合
我们来看下其中的Collections.toList(),源码如下:
public static <T>
Collector<T, ?, List<T>> toList() {
return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
(left, right) -> { left.addAll(right); return left; },
CH_ID);
}
CollectorImp前两个参数用了最简单的写法,完整写法如下:
return new CollectorImpl<>((Supplier<List<T>>) () -> new ArrayList<>(), (List<T> a, T b) -> { a.add(b); },
(left, right) -> { left.addAll(right); return left; },
CH_ID);
或者第一个参数不显式设置强转,通过第二个参数a就已经确定泛型的类型了,如下:
return new CollectorImpl<>(() -> new ArrayList<>(), (List<T> a, T b) -> { a.add(b); },
(left, right) -> { left.addAll(right); return left; },
CH_ID);
测试代码:
public class StreamDemo {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(4, 2, 3, 5, 1, 2, 2, 7, 6);
// 中间操作fillter
System.out.println("fillter: " + list.stream().parallel().filter((v) -> v > 5).collect(Collectors.toList()));
// distinct去重
System.out.println("distinct: " + list.stream().parallel().distinct().collect(Collectors.toList()));
// limit 限制元素个数
System.out.println("limit: " + list.stream().limit(3).collect(Collectors.toList()));
// skip 跳过前n个元素
System.out.println("skip: " + list.parallelStream().skip(7).collect(Collectors.toList()));
// map 拼加A转成字符串
System.out.println("map: " + list.parallelStream().map((v) -> v + "A").collect(Collectors.toList()));
// mapToDouble 转Double
System.out.println("mapToDouble: " + list.parallelStream().mapToDouble((v) -> v).boxed().collect(Collectors.toList()));
// mapToInt 转Integer
System.out.println("mapToInt: " + list.parallelStream().mapToInt((v) -> v).boxed().collect(Collectors.toList()));
// flatMap
List<List<String>> list111 = new ArrayList<>();
List<String> listA = new ArrayList<>();
listA.add("A1");
listA.add("A2");
List<String> listB = new ArrayList<>();
listB.add("B1");
listB.add("B2");
list111.add(listA);
list111.add(listB);
System.out.println("flatMap: " + list111.stream().flatMap(v -> v.stream()).collect(Collectors.toList()));
// sorted
// List list = Arrays.asList(4, 2, 3, 5, 1, 2, 2, 7, 6);
System.out.println("sorted: " + list.stream().parallel().sorted().collect(Collectors.toList()));
// sorted(Comparator)
System.out.println("sorted(Comparator): " + list.stream().sorted((o1, o2) -> o2 - o1).collect(Collectors.toList()));
// 终止操作 anyMatch
System.out.println("anyMatch: " + list.stream().anyMatch(v -> v > 6));
// 终止操作 allMatch
System.out.println("allMatch: " + list.stream().allMatch(v -> v < 0));
// reduce 求和 初始值给0
// 计算过程 0+list[0] = result1 result1+list[1]=result2 ...
System.out.println("reduce 求和 初始值给0 : " + list.stream().reduce(0, (v1, v2) -> v1 + v2));
// reduce 求积 初始值给1
// 计算过程 1*list[0] = result1 result1*list[1]=result2 ...
System.out.println("reduce 求积 初始值给1 : " + list.stream().reduce(1, (v1, v2) -> v1 * v2));
// findFirst
System.out.println("findFirst: " + list.stream().findFirst().get());
// findAny
System.out.println("findAny: " + list.stream().findAny().get());
// max
System.out.println("max: " + list.stream().max((v1, v2) -> v1 - v2).get());
// count 大于4的个数
System.out.println("count 大于4的个数: " + list.stream().filter(v -> v > 4).count());
}
}
运行:
fillter: [7, 6]
distinct: [4, 2, 3, 5, 1, 7, 6]
limit: [4, 2, 3]
skip: [7, 6]
map: [4A, 2A, 3A, 5A, 1A, 2A, 2A, 7A, 6A]
mapToDouble: [4.0, 2.0, 3.0, 5.0, 1.0, 2.0, 2.0, 7.0, 6.0]
mapToInt: [4, 2, 3, 5, 1, 2, 2, 7, 6]
flatMap: [A1, A2, B1, B2]
sorted: [1, 2, 2, 2, 3, 4, 5, 6, 7]
sorted(Comparator): [7, 6, 5, 4, 3, 2, 2, 2, 1]
anyMatch: true
allMatch: false
reduce 求和 初始值给0 : 32
reduce 求积 初始值给1 : 20160
findFirst: 4
findAny: 4
max: 7
count 大于4的个数: 3