java Stream使用介绍

何为Stream

关于Stream,官方的说法为:支持顺序和并行聚合操作的一系列元素。根据上述的描述,Stream主要的作用就是排序和对集合进行相关的操作。
通常来说,官方对于这块的说法有:

  • 他是惰性的,只有当需要用到时才会对其进行处理。
  • 大多数的操作行为都是通过用户参数指定的。
  • 用户指定的参数行为不应对流本身进行修改。
  • 大多数情况下必须时无状态的。
    就是说,流指挥在需要时才会执行相关操作,大部分操作都必须由用户控制,用户不应当修改流本身,也不支持操作状态返回。

流的基本操作

获取一个流

流的获取可以由数据直接获取,也可以从一个集合中获取。

1. 从数据中获取

        Stream<String> s = Stream.of("1", "2", "3", "4");

2. 从集合获取

        List<String> list = Arrays.asList("1", "2", "3", "4", "5");
        Stream<String> s = list.stream();

对流进行操作

排序

这里的排序其实和Collections.sort用法是一致的,如果不传比较器,对象必须是实现了Comparable接口才行。或者我们要传入一个Comparator的实现。

        Stream<String> s = Stream.of("1", "3", "2", "4");
        s.sorted().forEach(System.out::println);

输出的结果为

1
2
3
4

如果我们要想按我们自己的想法进行排序,那就要传入自己的算法:
例如下面一段:

        Stream<String> s = Stream.of("11", "3", "2", "4");
        s.sorted().forEach(System.out::println);

输出的结果为

11
2
3
4

如果我们想用数字的方式排序,那么我们应当这样:

        Stream<String> s = Stream.of("11", "3", "2", "4");
        s.sorted(Comparator.comparing(Integer::valueOf)).forEach(System.out::println);

输出的结果为

2
3
4
11

去重

Stream提供了内置的去重方法 Stream.distinct(),使用后可以对流中的元素进行去重处理,同时这个操作可以和上述的排序进行嵌套的操作。

例如如下例子:

        Stream<String> s = Stream.of("1", "3", "1", "4", "1", "2");
        s.distinct().sorted().forEach(System.out::println);

输出的结果为:

1
2
3
4

这个处理让我们去除了重复的元素之后再进行排序。

剔除数据

这个场景是指我们可以剔除满足指定条件的记录,例如我们要剔除流中值不为1的记录:

        Stream<String> s = Stream.of("1", "3", "1", "4", "1", "2");
        s.filter(s1 -> !"1".equals(s1)).forEach(System.out::println);

这样就会得到不为1的值:

3
4
2

对数据进行分页

Stream同时提供了skip和limit方法实现分页,这两个方法分别是跳过多少个值和取前几位。例如一个有7条的数据,我们想要获取第三页的数据(第5到第6条),那么就可以这样:

        Stream<String> s = Stream.of("1", "2", "3", "4", "5", "6", "7");
        s.skip(4).limit(2).forEach(System.out::println);

这个方法虽然可以进行分页,但是他不能多次分页,每次分页必须重新创建一个Stream对象,好处就是,分页时如果超出页数,不会报数组下标越界的错误。

累加器

对于我来说,累加器在实际场景中用的并不多,他主要用于求和运算,当然也可以用于字符串的累加等。下面就用几个例子来说明累加器的用途。这里就不做详细的阐述了。
对一系列的数字求和:

        Stream<Integer> s = Stream.of(1, 2, 3, 4, 5, 6, 7);
        System.out.println(s.reduce(0, (a, b) -> a + b)); // 结果为 28

对一系列的数字累乘:

        Stream<Integer> s = Stream.of(1, 2, 3, 4, 5, 6, 7);
        System.out.println(s.reduce(1, (a, b) -> a * b));  // 结果为 5040

字符串求和:

        Stream<String> s = Stream.of("1", "2", "3", "4", "5", "6", "7");
        System.out.println(s.reduce("", (a, b) -> a + b));  // 结果为 1234567

当然,上面的例子其实都可以没有初始值,这时返回的就是一个Optional对象,以字符串的例子为例,也可以这样写:

        Stream<String> s = Stream.of("1", "2", "3", "4", "5", "6", "7");
        System.out.println(s.reduce((a, b) -> a + b));  // 结果为 Optional[1234567]

最大与最小

Stream.maxStream.min方法可以取得流的最大与最小值。但这个必须传一个比较器。

日志

这里说的日志是指对Stream中的对象进行操作时进行的记录,通常我们不会用,常见于调试,方法为Stream.peek(Consumer),详细使用我就不细述了,就举一个例子:

        Stream<Integer> s = Stream.of(1, 2, 3, 4, 5, 6, 7);
        System.out.println(s.peek(System.out::println).reduce((a, b) -> a + b));

输出结果:

1
2
3
4
5
6
7
Optional[28]

转成集合

如果需要把流转换成集合,我们可以直接调用collect方法。这个也是Stream中最花里胡哨的方法,应该也是我们平时用到的最多的方法,经测试,效率比我们遍历处理会略高,但是并没有高太多。

流转list
        Stream<String> s = Stream.of("11", "3", "2", "4");
        List<String> list = s.sorted(Comparator.comparing(Integer::valueOf)).collect(Collectors.toList());

如果你需要把流转成其他的类型的list,那么你只需要这样:

        Stream<String> s = Stream.of("11", "3", "2", "4");
        Stream<Integer> list = s.sorted(Comparator.comparing(Integer::valueOf)).map(a -> Integer.valueOf(a));
流转set
		Set<String> set = s.collect(Collectors.toSet());
流转Map
		Map<String, Integer> map = s.collect(Collectors.toMap(s1 -> s1, Integer::parseInt));

这里前面的方法是用值生成map的key,后面的方法则是用值生成对应的map的值。

分组
		Stream<Integer> s = Stream.of(1, 1, 2, 2, 3, 3, 4);
        Map<Integer, List<Integer>> map = s.collect(Collectors.groupingBy(i->i));
        System.out.println(map);

输出结果:

{1=[1, 1], 2=[2, 2], 3=[3, 3], 4=[4]}

结语

以上就是Stream的常用操作,当然它还有很多的用法没有介绍,这些用法在品是工作中比较少使用,如果感兴趣的,可以自己探索。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java StreamJava 8 中新增的一个 API,用于处理集合数据。它提供了一种更加简洁、高效的方式来操作集合,可以让代码更加简洁、易读、易维护。下面是 Java Stream 的基本使用方法: 1. 创建 Java Stream 可以从多种数据源中创建,比如集合、数组、文件等。例如,从集合创建一个 Stream 可以使用以下代码: ```java List<String> list = new ArrayList<>(); Stream<String> stream = list.stream(); ``` 2. 中间操作 中间操作是指对 Stream 进行操作,返回一个新的 Stream。常见的中间操作包括:filter、map、sorted、distinct 等。例如,下面的代码使用 filter 操作过滤出长度大于 5 的字符串: ```java List<String> list = Arrays.asList("apple", "banana", "orange", "watermelon"); Stream<String> stream = list.stream().filter(s -> s.length() > 5); ``` 3. 终止操作 终止操作是指对 Stream 进行最终的操作,返回一个非 Stream 的结果。常见的终止操作包括:forEach、reduce、collect、count 等。例如,下面的代码使用 forEach 操作输出过滤后的字符串: ```java List<String> list = Arrays.asList("apple", "banana", "orange", "watermelon"); list.stream().filter(s -> s.length() > 5).forEach(System.out::println); ``` 4. 短路操作 短路操作是指对 Stream 进行操作时,只要满足一定条件就可以停止操作,不必对整个进行操作。常见的短路操作包括:findFirst、findAny、allMatch、anyMatch、noneMatch 等。例如,下面的代码使用 findAny 操作找到第一个长度大于 5 的字符串: ```java List<String> list = Arrays.asList("apple", "banana", "orange", "watermelon"); Optional<String> result = list.stream().filter(s -> s.length() > 5).findAny(); ``` 以上就是 Java Stream 的基本使用方法,需要注意的是,Stream 是一次性的,一旦进行了终止操作,就不能再对该 Stream 进行操作。同时,Stream 也是惰性求值的,只有在终止操作时才会进行真正的计算。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值