Java流式操作
简介:Stream 中文称为 “流”,通过将集合转换为这么一种叫做 “流” 的元素序列,通过声明性方式,能够对集合中的每个元素进行一系列并行或串行的流水线操作。
操作分类:
常见流操作API
中间操作
filter(): 对元素进行过滤
map():元素映射
sorted():对元素排序
distinct():去除重复的元素
最终操作:
forEach():遍历每个元素。
findFirst():找第一个符合要求的元素。
reduce():把Stream 元素组合起来。例如,字符串拼接,数值的 sum,min,max ,average 都是特殊的 reduce。
collect():返回一个新的数据结构,基于Collectors有丰富的处理方法。
min():找到最小值。
max():找到最大值。
中间操作:中间操作包括去重、过滤、映射等操作,值得说明的是,如果没有为流定义终端操作,为了避免无谓的计算,中间操作也不会执行
终端操作:终端产生最终的执行结果,并中断流式编程的衔接链,因此结束操作是最后一个操作
案例说明
以下案例基于初始数据,生成代码如下:
private static List<DemoVO> initList(){
List<DemoVO> list = new ArrayList<>();
DemoVO demo1 = new DemoVO();
demo1.setKey("a");
demo1.setValue("str-a");
list.add(demo1);
DemoVO demo2 = new DemoVO();
demo2.setKey("b");
demo2.setValue("str-b");
list.add(demo2);
DemoVO demo3 = new DemoVO();
demo3.setKey("c");
demo3.setValue("str-c");
list.add(demo3);
return list;
}
1.filter过滤
private static void testFilter(List<DemoVO> list){
List<DemoVO> listNew = list.stream().filter(item->item.getKey().equals("a")).collect(Collectors.toList());
System.out.println(JSON.toJSONString(listNew));
}
输出结果:
[{"key":"a","value":"str-a"}]
2.Map映射
private static void listToMap(List<DemoVO> list){
Map<String,DemoVO> demoMap1 = list.stream().collect(Collectors.toMap(DemoVO::getKey, Function.identity()));
//当出现同名Key时,用后者替换前者,toMap跟进源码可以看到使用了BinaryOperator类作为参数,BinaryOperator接收两个同样类型的实参,返回和参数同样类型的结果类型
Map<String,DemoVO> demoMap2 = list.stream().collect(Collectors.toMap(DemoVO::getKey, Function.identity(),(key1, key2) -> key2));
System.out.println(JSON.toJSONString(demoMap1));
}
输出结果:
{"a":{"key":"a","value":"str-a"},"b":{"key":"b","value":"str-b"},"c":{"key":"c","value":"str-c"}}
3.sorted排序
private static void testSorted(List<DemoVO> list){
//自然排序,先对key进行排序,再对value进行排序。
List<DemoVO> collect = list.stream().sorted(Comparator.comparing(DemoVO::getKey).thenComparing(DemoVO::getValue)).collect(Collectors.toList());
System.out.println(JSON.toJSONString(collect));
collect = list.stream().sorted(Comparator.comparing(DemoVO::getKey).thenComparing(DemoVO::getValue)).collect(Collectors.toList());
System.out.println(JSON.toJSONString(collect));
}
输出结果:
[{"key":"a","value":"str-a"},{"key":"b","value":"str-b"},{"key":"c","value":"str-c"}]
4.distinct去重
//原始数据新增
DemoVO demo4 = new DemoVO();
demo4.setKey("c");
demo4.setValue("str-c");
list.add(demo4);
//去重
private static void testDistinct(List<DemoVO> list){
List<DemoVO> collect = list.stream().distinct().collect(Collectors.toList());
System.out.println(JSON.toJSONString(collect));
}
//输出结果
[{"key":"a","value":"str-a"},{"key":"b","value":"str-b"},{"key":"c","value":"str-c"}]
5.List转List
private static void convertToList(List<DemoVO> list){
List<String> collect = list.stream().map(DemoVO::getValue).collect(Collectors.toList());
System.out.println(JSON.toJSONString(collect));
}
//输出结果
["str-a","str-b","str-c"]
Lambda 表达式
Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。
Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
使用 Lambda 表达式可以使代码变的更加简洁紧凑。
lambda 表达式的语法格式如下:
(parameters) -> expression
或
(parameters) ->{ statements; }
以下是lambda表达式的重要特征:
可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定表达式返回了一个数值。
Lambda 表达式实例
Lambda 表达式的简单例子:
// 1. 不需要参数,返回值为 5
() -> 5
// 2. 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x
// 3. 接受2个参数(数字),并返回他们的差值
(x, y) -> x – y
// 4. 接收2个int型整数,返回他们的和
(int x, int y) -> x + y
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)