【JAVA基础】Stream的操作流程

为什么需要使用Stream

Stream 的操作流程

  • 获取一个数据源(source)
  • 中间数据操作
    执行中间操作,每次转换原有 Stream 对象不改变,返回一个新的 Stream 对象(可以有多次转换),这就允许对其操作可以像链条一样排列,变成一个管道
  • 终止操作,获得想要的结果
    如下图所示:

Intermediate(中间数据操作):
map (mapToInt, flatMap 等)、 filter、 distinct、 sorted、 peek、 limit、 skip、 parallel、 sequential、 unordered

Terminal(终止操作):
forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 iterator

Short-circuiting(短路操作):
anyMatch、 allMatch、 noneMatch、 findFirst、 findAny

获取一个数据源(source)

  • Collection 和数组Arrays中的静态方法
    Collection.stream();Collection.parallelStream()
    Arrays.stream(T array) or Stream.of()
    例如:
	Stream<String> listStream = Arrays.asList("aa","bb","cc").stream();
	String[] stringArray = {"aa","bb","cc"};
	Stream<String> arrayStream = Arrays.stream(stringArray);
  • 通过Stream类中的一些静态方法获取流
    例如 Stream.of();Stream.iterate();Stream.generate()
	Stream<String> stream = Stream.of("aa","bb","cc");
    Stream<Integer> stream1 = Stream.iterate(2, (x) -> x * 2);
    Stream<Double> stream2 = Stream.generate(() -> Math.random());
  • 其它一些类,可以获取stream对象
	java.nio.file.Files.walk()
	Random.ints()
	BitSet.stream()
	Pattern.splitAsStream(java.lang.CharSequence)
	JarFile.stream()
	ava.io.BufferedReader.lines()

中间数据操作

即对数据的流进行一些需要的操作,在终止操作执行之前,中间操作可以不断执行。
如图:

中间操作主要用到strem类提供的一些可以返回Stream流的静态方法,主要示例一些常用的方法,其他可参考在线中文JDK1.8 http://www.matools.com/api/java8

filter(Predicate<? super T> predicate)

顾名思义,过滤输入流中的一些元素,只输出符合条件的一些元素,需要给定筛选条件(Predicate<? super T> predicate)
举例说明:

	 Stream<String> listStream = Arrays.asList("aa","bb","cc").stream();
     Stream<String> handledStream = listStream.filter(a -> "aa".equals(a));
     System.err.println("filter after:" + handledStream.collect(Collectors.toList()));

输出结果为:
在这里插入图片描述
从结果中可以看出来,原有数组中[“aa”,“bb”,“cc”],经过过滤条件 “aa”.equals(a) 的筛选以后,新输出的数组,只剩下了符合条件的[“aa”]。
此处可能会产生两个疑问:

  1. 此时如果执行System.err.println("before:" + listStream.collect(Collectors.toList()));会报错,为什么呢?
    流只能被读一遍,详细见后文
  2. handledStream.collect(Collectors.toList())是什么意思呢?
    将流转换为List,方便输出查看结果,详细见后文

按照上面的思路,把Stream中的一些静态方法都执行一遍,看每个静态方法都有什么作用。

distinct()

返回由该流的不同元素(根据 Object.equals(Object) )组成的流。即去重的意思

  @Test
  public void streamDistinctTest() {
    Stream<String> listStream = Arrays.asList("aa","aa", "bb", "cc", "eee", "cc").stream();
    Stream<String> handledStream = listStream.distinct();
    System.err.println("distinct after:" + handledStream.collect(Collectors.toList()));
  }

结果如下:
在这里插入图片描述
从结果中看,原数组为[“aa”,“aa”, “bb”, “cc”, “eee”, “cc”],distinct之后,重复的"aa","cc"被去除掉了。
上文中的 “根据 Object.equals(Object)” 又是什么意思呢,即如果传入是一个Object对象,判断是否重复的办法是调用equels方法去重,如果需要实现自己的去重规则,需要重写对象中的equels方法。

limit(long maxSize)

返回由此流的元素组成的流,截短长度不能超过 maxSize。即截取maxSize长度的数据。

  @Test
  public void streamLimitTest() {
    Stream<String> listStream = Arrays.asList("aa","aa", "bb", "cc", "eee", "cc").stream();
    Stream<String> handledStream = listStream.limit(3);
    System.err.println("limit after:" + handledStream.collect(Collectors.toList()));
  }

结果如下:
在这里插入图片描述

skip(long n)

丢弃前n个元素,只保留后面的元素

  @Test
  public void streamSkipTest() {
    Stream<String> listStream = Arrays.asList("aa", "bb", "cc", "eee", "cc").stream();
    Stream<String> handledStream = listStream.skip(2);
    System.err.println("skip after:" + handledStream.collect(Collectors.toList()));
  }

结果如下:
在这里插入图片描述
从结果中可以看出来,skip跳过了前两个元素,只返回了后三个元素

sorted()

返回由此流的元素组成的流,根据自然顺序排序。

  @Test
  public void streamSortTest() {
    Stream<String> listStream = Arrays.asList("hh", "gg", "ee", "dd", "cc").stream();
    Stream<String> handledStream = listStream.sorted();
    System.err.println("sorted after:" + handledStream.collect(Collectors.toList()));
  }

结果如下:
在这里插入图片描述
从结果中可以看到,对原数组[“hh”, “gg”, “ee”, “dd”, “cc”],进行了一个字符串的排序

map

map()方法为流中的每个输入值生成一个输出值。
因此,如果流中有n个元素,则map()操作将生成n个输出元素的流。

  @Test
  public void streamMapTest() {
    List<String> listOfStrings = Arrays.asList("1", "2", "3", "4", "5");

    List<Integer> listOfIntegers = listOfStrings.stream()
                                    .map(Integer::valueOf)
                                    .collect(Collectors.toList());

    System.err.println(listOfIntegers);
  }

在这里插入图片描述

flatMap

flatMap()是两步过程,即map()+ Flattening。
它有助于将Collection <Collection >转换为Collection 。

  @Test
  public void streamFlatMapTest() {
    List<Integer> list1 = Arrays.asList(1,2,3);
    List<Integer> list2 = Arrays.asList(4,5,6);
    List<Integer> list3 = Arrays.asList(7,8,9);
     
    List<List<Integer>> listOfLists = Arrays.asList(list1, list2, list3);
     
    List<Integer> listOfAllIntegers = listOfLists.stream()
                                .flatMap(x -> x.stream())
                                .collect(Collectors.toList());
     
    System.err.println(listOfAllIntegers);
  }

在这里插入图片描述

终止操作

forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 iterator、collect

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值