写给大忙人的javaSE8(2)-常用流操作

如果前方的路是黑暗的,那应该先找到指路的灯

java8中的 StreamAPI 非常丰富,本文介绍几种比较重要的API。

  1. collect(toList()) 这个方法是用于生成一个列表, 是一个及早求值操作.
    下面看一段示例代码
List<String> collected = Stream.of("a", "b", "c").
    collect(Collectors.toList());

assertEquals(Arrays.asList("a", "b", "c"), collected);

上一篇文章中说过,Stream中的很多操作都是惰性求值,因此在Stream中的一系列方法之后,需要调用一个collect的及早求值方法,从而得到一个List<String>,下面这句是用断言测试工具测试结果是否为预期的。

  1. map操作可以将一个流中的值转换成一个新的流
    下面看一段示例代码
//使用map操作
List<String> collected = Stream.of("a", "b", "hello")
        .map(str -> str.toUpperCase()).collect(Collectors.toList());

assertEquals(Arrays.asList("A", "B", "HELLO"), collected);

传给map的lambda表达式只接受一个String类型的参数,返回一个新的String。参数和返回值不必属于同一种类型,但是lambda表达式必须是Function接口的一个实例,Function接口是只包含一个参数的普通函数接口。
map操作一开始理解起来有点抽象。 在看看下面这个例子

//使用map操作
List<Integer> collected2 = Stream.of(1, 2, 3).map(i32 -> i32 + 1)
        .collect(Collectors.toList());
collected2.stream().forEach(i32 -> {
    System.out.println(i32);
});

assertEquals(Arrays.asList(2, 3, 4), collected2);

这里通过实现map中的 Function接口,来对数据进行 +1 的操作。

3.filter 遍历数据并检查其中的元素。

//使用filter操作
List<String> beginningWithNumbers = Stream.of("a", "abc", "1abc").
        filter(value -> isDigit(value.charAt(0))).collect(Collectors.toList());
assertEquals(Arrays.asList("1abc"), beginningWithNumbers);

和map很像, filter接收一个函数作为参数,该函数用lambda表达式表示。该函数和前面实例中if条件判断语句的功能一样,如果字符串首字母为数字,则返回true,因此若要重构遗留的代码,for循环中的if条件语句就可以用filter方法替代。

  1. flatMap
    前面的map操作,它可用一个新的值代替Stream中的值,但有时,用户希望让map操作有点变化,生成一个新的Stream对象代替它,但是又不希望结果是一连串的流,此时flatMap最能派上用场。 看下面的例子。
//使用flatMap
List<Integer> together = Stream.of(Arrays.asList(1, 2), Arrays.asList(3, 4))
        .flatMap(numbers -> numbers.stream()).
collect(Collectors.toList());

assertEquals(Arrays.asList(1, 2, 3, 4), together);

用flatMap实际上是将每个列表转换成 Stream对象,其余部分由flatMap方法处理。flatMap方法相关函数接口和map方法一样, 都是 Function接口,只是方法的返回值限定为Stream类型了。通俗一点的讲,就是将参数都转换成stream,形成了一个stream在通过及早求执方法 collect()得到一个 together的 List<Integer>

  1. max 和 min操作。

max和min是Stream上比较常用的操作。例如下代码中,找到track中字段num值最小的一条

List<Track> tracks = Arrays.asList(
        new Track("第二天堂", 15),
        new Track("大将军", 8),
        new Track("荒野猎人", 20));
Track shortestTrack = tracks.stream()
        .min(Comparator.comparing(track -> track.getNum())).get();

assertEquals(tracks.get(1), shortestTrack);

max或min方法需要指定一个排序指标作为甄选依据,示例代码中我们指定了num字段作为排序依据,同理,需要获取最大值时,只需要改用max方法即可。为了让Stream对象按照track的长度进行排序,需要传一个Comparator对象,java8 中提供了一个新的静态方法, comparing,使用它可以方便地实现一个比较器。
6.reduce操作
reduce操作可以实现从一组值中生成一个值,实际上 count ,max,min等因为比较常用,所以被纳入了标准库中,其实这些方法都是reduce操作,先看一段代码

//点定义一个 BinaryOperator并指定它的结果是由 第一个参数+第二个参数组成的
BinaryOperator<Integer> accumulator = (acc, element) -> acc + element;
//紧接着,模拟每一次的操作
int count2 = accumulator.
  apply(accumulator.
                apply(accumulator.
                              apply(0, 1)
                , 2)
  , 3);

这里先从最内部开始,第一个值 0,1相加得到1,第二层 1,2 相加得到3 ,最外面一层,3加3等于6,实际上,他的操作方式就是我们在上面代码第一行定义的。 然后改成使用reduce方式在看看代码是怎么实现的呢?

int count = Stream.of(1, 2, 3).reduce(0, (acc, element) -> acc + element);

在使用Stream的reduce操作时,实际上就是将集合中的参数,以0为起点,按照两个参数传入Stream中的当前元素和 acc。将两个参数相加,acc在这里实际上就是累加器,保存着当前的累加结果。
此类的计算方式,在引入java8之前,我们还需要使用for循环,另外定义一个累加器,每次循环取出数据进行累加,并更新打累加器。 如果使用了reduce方式,是不是方便了很多呢。

其实我们也可以通过reduce来实现诸如 max, min的方法

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

推荐阅读更多精彩内容