美文网首页
写给大忙人的javaSE8(2)-常用流操作

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

作者: 青山有扶苏 | 来源:发表于2019-02-26 00:42 被阅读0次
如果前方的路是黑暗的,那应该先找到指路的灯

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);
你值得拥有最好的自己

相关文章

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

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

  • 写给大忙人的javaSE8(3)-流操作使用总结

    温馨提示:这一接基本上是前面一节中的一些总结和使用注意事项,可以酌情跳过。 前面一节中,说明了常用的Stream操...

  • Java面试相关书籍

    Java SE 写给大忙人看的Java核心技术:Core Java压缩版 写给大忙人看的Java SE 8:Jav...

  • 常用流操作

  • 第五章 使用流

    1、Streams API可以表达复杂的数据处理查询。常用的流操作总结如下: 2、流的筛选(filter、dist...

  • JavaSE8流库

    一、流库介绍 1.1 流提供了一种让我们可以在比集合更高的概念级别上指定计算的数据视图。通过流,我们可以说明想要完...

  • 并发知识6

    对并发散列映射的批操作 javase8 为散列映射提供批操作,即使有其他线程在处理映射,这些操作也能安全的执行。批...

  • Java8实战读书笔记3-使用流

    一、流的常用操作 筛选:filter、distinct 截断、跳过:limit、skip 映射:map 流的扁平化...

  • java8系列-04 Stream

    Stream英文直译为“流”,其实这里也是对文件流、集合流等各种流的操作。(虽然我们最常用在Collection集...

  • Java基础笔记总结(13)-IO流(1)FileInputSt

    IO流 IO流通常用来处理设备之间的数据传输 Java对数据的操作是通过流的形式 Java用于操作的流的类都在IO...

网友评论

      本文标题:写给大忙人的javaSE8(2)-常用流操作

      本文链接:https://www.haomeiwen.com/subject/jhcoyqtx.html