恐怖!深夜一乞丐在路上画出Java Stream 知识脑图


Java Stream 流式处理

一、流概念

1. 结构

流获取

转换操作 : 可以有多个

终止操作 : 只能有一个

2. 类型

stream() : 单管道

parallelStream()

多管道,并行流式处理,底层使用 ForkJoinPool 实现

强制要求有序 : forEachOrdered()

List list = Arrays.asList(1,2,3,4,5,6,7);//结果:1234567list.stream().forEach(System.out::print);//结果:5726134list.parallelStream().forEach(System.out::print);//结果:1234567list.parallelStream().forEachOrdered(System.out::print);复制代码

3. 函数式接口

接口中有且仅有一个抽象方法

常见接口

接口参数返回值类别

ConsumerTvoid消费型接口

SupplierNoneT供给型接口

FunctionTR函数型接口

PredicateTboolean断言型接口

4. Lambda 表达式

结构 : (参数) ‐> { 代码语句 }

用于简化 函数式接口 的编写

可以延迟运行,提升性能

二、流 获取

1. Collection 子接口

直接调用 stream() 方法

List

Set

Vector

List list =newArrayList<>();Stream stream1 = list.stream();Set set =newHashSet<>();Stream stream2 = set.stream();Vector vector =newVector<>();Stream stream3 = vector.stream();复制代码

2. Map

不是 Collection 子接口,其 K-V 数据结构不符合流元素特征,所以需根据 Key、Value、Entry 分别获取

Map map =newHashMap<>();// ...Stream keyStream = map.keySet().stream();Stream valueStream = map.values().stream();Stream> entryStream = map.entrySet().stream();复制代码

3. Array

数组无法添加默认方法,故使用 Stream.of() 方法获取

String[] array = {"张无忌","张翠山","张三丰","张一元"};Stream stream = Stream.of(array);复制代码

二、转换 操作

1. filter( T -> boolean )

过滤数据,保留条件为 true 的元素

List list = Arrays.asList(20,23,25,28,30,33,37,40);//从指定数据集合中过滤出大于等于30的数据集合List collect = list.stream().filter(x -> x >=30).collect(Collectors.toList());//结果:[30, 33, 37, 40]System.out.println(collect);复制代码

2. map( T -> R )

转换数据,将转换后的数据存回流中

List list = Arrays.asList("1","2","3","4","5","6");List collect1 = list.stream().map(x -> Long.parseLong(x)).collect(Collectors.toList());//结果:[1, 2, 3, 4, 5, 6]System.out.println(collect1);//结果:111111list.stream().mapToInt(x -> x.length()).forEach(System.out::print);System.out.println("");//结果:111111list.stream().mapToLong(x -> x.length()).forEach(System.out::print);System.out.println("");//结果:1.01.01.01.01.01.0list.stream().mapToDouble(x -> x.length()).forEach(System.out::print);复制代码

3. flatMap( T -> Stream )

将流中的 元素 映射为一个 流,再把每个流连接为一个流

List>  list =newArrayList>(){{            add(Lists.newArrayList("a","b","c"));            add(Lists.newArrayList("d","e","f"));            add(Lists.newArrayList("j","k","y"));        }};//结果:[[a, b, c], [d, e, f], [j, k, y]]System.out.println(list);List collect = list.stream().flatMap(List::stream).collect(Collectors.toList());//结果:[a, b, c, d, e, f, j, k, y]System.out.println(collect);复制代码

4. distinct()

元素去重,底层使用 equals() 方法做比较

List list = Arrays.asList("a","b","ab","abc","a","ab","a","abcd","bd","abc");List collect = list.stream().distinct().collect(Collectors.toList());//结果:[a, b, ab, abc, abcd, bd]System.out.println(collect);复制代码

5. sorted( T -> boolean )

元素排序,需事前 实现 Comparable 接口 或 自定义比较器

List list = Arrays.asList(5,3,7,1,4,6);List collect = list.stream().sorted((a, b) -> a.compareTo(b)).collect(Collectors.toList());//结果:[1, 3, 4, 5, 6, 7]System.out.println(collect);复制代码

6. limit( num )

限制返回的元素个数

List list = Arrays.asList("a","b","ab","abc","a","ab","a","abcd","bd","abc");List collect = list.stream().limit(3).collect(Collectors.toList());//结果:[a, b, ab]System.out.println(collect);复制代码

7. skip( num )

跳过元素

List list = Arrays.asList("a","b","ab","abc","a","ab","a","abcd","bd","abc");List collect = list.stream().skip(5).collect(Collectors.toList());//结果:[ab, a, abcd, bd, abc]System.out.println(collect);复制代码

8. peek( T -> void )

挑出元素进行操作,但操作后的元素不返回到流中

List list = Arrays.asList("a","b","ab","abc","a","ab","a","abcd","bd","abc");//结果:abababcaabaabcdbdabclist.stream().peek(x -> x.toUpperCase()).forEach(System.out::print);//结果:ABABABCAABAABCDBDABClist.stream().map(x -> x.toUpperCase()).forEach(System.out::print);复制代码

三、终止 操作

1. forEach

forEach : 支持并行处理

forEachOrdered : 强制要求有序处理,速度较慢

List list = Arrays.asList("a","b","ab");//结果:a b ablist.stream().forEach(x -> System.out.print(x+' '));System.out.println("");//可以简化//结果:a b ablist.forEach(x -> System.out.print(x+' '));System.out.println("");//结果:a b ablist.stream().forEachOrdered(x -> System.out.print(x+' '));复制代码

2. collect

toMap : 将 数据流 转换成 Map,里面包含的元素是 key / value 形式

toSet : 将 数据流 转换成 Set,里面包含的 元素不可重复

toList : 将 数据流 转换成 List,里面包含的 元素有序

joining : 元素间 拼接 分割符,并返回 字符串

groupingBy : 分组,可以将 List 转换成 Map

couting : 统计 元素数量

maxBy : 获取 最大的元素

minBy : 获取 最小的元素

summarizingInt : 汇总 Integer 类型的元素,返回 IntSummaryStatistics,可再调用具体方法进行统计

getCount : 统计数量

getSum : 求和

getMin : 获取最小值

getMax : 获取最大值

getAverage : 获取平均值

summarizingLong : 汇总 Long 类型元素,用法同 summarizingInt

summarizingDouble : 汇总 Double 类型元素,用法同 summarizingInt

averagingInt : 获取 Integer 元素平均值,返回一个 Double 类型数据

averagingLong : 获取 Long 元素平均值,返回一个 Double 类型数据

averagingDouble : 获取 Double 元素平均值,返回一个 Double 类型数据

mapping : 获取映射,可以将原始元素的一部分内容作为一个新元素返回

List list0 = Arrays.asList("a","b","ab");Map collect0 = list0.stream().collect(Collectors.toMap(String::new, Function.identity()));//结果:{ab=ab, a=a, b=b}System.out.println(collect0);List list = Arrays.asList("a","b","ab","a","b","ab");List collect1 = list.stream().collect(Collectors.toList());//结果:

[a, b, ab, a, b, ab]System.out.println(collect1);//结果:

[a, ab, b]Set collect2 = list.stream().collect(Collectors.toSet());

System.out.println(collect2);String collect3 = list.stream().collect(Collectors.joining(","));//结果:a,b,ab,a,b,abSystem.out.println(collect3);

Map collect4 = list.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

//结果:{ab=2, a=2, b=2}System.out.println(collect4);

Long collect = list.stream().collect(Collectors.counting());

//结果:6System.out.println(collect);

List list1 = Arrays.asList(1,3,5,7,9,11);

Integer collect5 = list1.stream().collect(Collectors.maxBy((a, b) -> a.compareTo(b))).orElse(null);

System.out.println(collect5);

//结果:11System.out.println(collect5);

String collect6 = list1.stream().collect(Collectors.minBy((a, b) -> a.compareTo(b))).orElse(null);

//结果:1System.out.println(collect6);List list2 = Arrays.asList("2","3","5");

IntSummaryStatistics summaryStatistics = list2.stream().collect(Collectors.summarizingInt(x -> Integer.parseInt(x)));longsum = summaryStatistics.getSum();

//结果:10System.out.println(sum);

Double collect7 = list2.stream().collect(Collectors.averagingInt(x -> Integer.parseInt(x)));

//结果:3.3333333333333335System.out.println(collect7);

List userList =newArrayList() {{  add(newUser("jack",23)); 

add(newUser("james",30)); 

add(newUser("curry",28));}};List collect8 = userList.stream().collect(Collectors.mapping(User::getName, Collectors.toList()));

//[jack, james, curry]System.out.println(collect8);复制代码

3. find

findFirst : 查找第一个元素,返回的类型为 Optional

findAny : 一般返回第一个元素,返回的类型为 Optional,但如果是并行情况,则不保证是第一个

List lst1 = Arrays.asList("Jhonny","David","Jack","Duke","Jill","Dany","Julia","Jenish","Divya");List lst2 = Arrays.asList("Jhonny","David","Jack","Duke","Jill","Dany","Julia","Jenish","Divya"); Optional findFirst = lst1.parallelStream().filter(s -> s.startsWith("D")).findFirst();Optional fidnAny = lst2.parallelStream().filter(s -> s.startsWith("J")).findAny(); System.out.println(findFirst.get());// 总是打印出 DavidSystem.out.println(fidnAny.get());// 会随机打印出 Jack/Jill/Julia复制代码

4. match

allMatch : 所有元素都满足条件,返回 boolean 类型

anyMatch : 任意一个元素满足条件,返回 boolean 类型

noneMatch : 所有元素都不满足条件,返回 boolean 类型

List list = Arrays.asList(2,3,5,7);booleanallMatch = list.stream().allMatch(x -> x >1);//结果:trueSystem.out.println(allMatch);booleanallMatch2 = list.stream().allMatch(x -> x >2);//结果:falseSystem.out.println(allMatch2);booleananyMatch = list.stream().anyMatch(x -> x >2);//结果:trueSystem.out.println(anyMatch);booleannoneMatch1 = list.stream().noneMatch(x -> x >5);//结果:falseSystem.out.println(noneMatch1);booleannoneMatch2 = list.stream().noneMatch(x -> x >7);//结果:trueSystem.out.println(noneMatch2);复制代码

5. count

统计数量,返回 long 类型,与集合的 size() 方法类似

List list = Arrays.asList("a","b","ab");longcount = list.stream().count();//结果:3System.out.println(count);复制代码

6. max、min

max : 获取最大值,返回 Optional 类型

min : 获取最小值,返回 Optional 类型

List list = Arrays.asList(2,3,5,7);Optional max = list.stream().max((a, b) -> a.compareTo(b));//结果:7System.out.println(max.get());Optional min = list.stream().min((a, b) -> a.compareTo(b));//结果:2System.out.println(min.get());复制代码

7. reduce

规约操作,将整个数据流规约成一个值

两个参数 : 循环计算的初始值、计算累加器

count、max、min 底层就是使用 reduce 实现

List list = Arrays.asList(2,3,5,7);Integer sum1 = list.stream().reduce(0, Integer::sum);//结果:17System.out.println(sum1);Optional reduce = list.stream().reduce((a, b) -> a + b);//结果:17System.out.println(reduce.get());Integer max = list.stream().reduce(0, Integer::max);//结果:7System.out.println(max);Integer min = list.stream().reduce(0, Integer::min);//结果:0System.out.println(min);Optional reduce1 = list.stream().reduce((a, b) -> a > b ? b : a);//2System.out.println(reduce1.get());复制代码

8. toArray

数组操作,将 数据流 转换成 数组

List list = Arrays.asList("a","b","ab");String[] strings = list.stream().toArray(String[]::new);//结果:a b abfor(inti =0; i < strings.length; i++) {  System.out.print(strings[i]+" ");}复制代码

9. concat

将 两个流 合并为 一个流

Stream streamA = Stream.of("张无忌");Stream streamB = Stream.of("张翠山");Stream result = Stream.concat(streamA, streamB);

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容