GitHub 1.5k Star 的Java工程师成神之路 ,不来了解一下吗?java
GitHub 1.5k Star 的Java工程师成神之路 ,真的不来了解一下吗?git
GitHub 1.5k Star 的Java工程师成神之路 ,真的肯定不来了解一下吗?程序员
在Java中,集合和数组是咱们常常会用到的数据结构,须要常常对他们作增、删、改、查、聚合、统计、过滤等操做。相比之下,关系型数据库中也一样有这些操做,可是在Java 8以前,集合和数组的处理并非很便捷。github
不过,这一问题在Java 8中获得了改善,Java 8 API添加了一个新的抽象称为流Stream,可让你以一种声明的方式处理数据。本文就来介绍下如何使用Stream。特别说明一下,关于Stream的性能及原理不是本文的重点,若是你们感兴趣后面会出文章单独介绍。数据库
Stream 使用一种相似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。编程
Stream API能够极大提升Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。数组
这种风格将要处理的元素集合看做一种流,流在管道中传输,而且能够在管道的节点上进行处理,好比筛选,排序,聚合等。数据结构
Stream有如下特性及优势:dom
咱们举一个例子,来看一下到底Stream能够作什么事情:函数式编程
上面的例子中,获取一些带颜色塑料球做为数据源,首先过滤掉红色的、把它们融化成随机的三角形。再过滤器并删除小的三角形。最后计算出剩余图形的周长。
如上图,对于流的处理,主要有三种关键性操做:分别是流的建立、中间操做(intermediate operation)以及最终操做(terminal operation)。
在Java 8中,能够有多种方法来建立流。
一、经过已有的集合来建立流
在Java 8中,除了增长了不少Stream相关的类之外,还对集合类自身作了加强,在其中增长了stream方法,能够将一个集合类转换成流。
List<String> strings = Arrays.asList("Hollis", "HollisChuang", "hollis", "Hello", "HelloWorld", "Hollis");
Stream<String> stream = strings.stream();
复制代码
以上,经过一个已有的List建立一个流。除此之外,还有一个parallelStream方法,能够为集合建立一个并行流。
这种经过集合建立出一个Stream的方式也是比较经常使用的一种方式。
二、经过Stream建立流
可使用Stream类提供的方法,直接返回一个由指定元素组成的流。
Stream<String> stream = Stream.of("Hollis", "HollisChuang", "hollis", "Hello", "HelloWorld", "Hollis");
复制代码
如以上代码,直接经过of方法,建立并返回一个Stream。
Stream有不少中间操做,多个中间操做能够链接起来造成一个流水线,每个中间操做就像流水线上的一个工人,每人工人均可以对流进行加工,加工后获得的结果仍是一个流。
如下是经常使用的中间操做列表:
filter
filter 方法用于经过设置的条件过滤出元素。如下代码片断使用 filter 方法过滤掉空字符串:
List<String> strings = Arrays.asList("Hollis", "", "HollisChuang", "H", "hollis");
strings.stream().filter(string -> !string.isEmpty()).forEach(System.out::println);
//Hollis, , HollisChuang, H, hollis
复制代码
map
map 方法用于映射每一个元素到对应的结果,如下代码片断使用 map 输出了元素对应的平方数:
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
numbers.stream().map( i -> i*i).forEach(System.out::println);
//9,4,4,9,49,9,25
复制代码
limit/skip
limit 返回 Stream 的前面 n 个元素;skip 则是扔掉前 n 个元素。如下代码片断使用 limit 方法保理4个元素:
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
numbers.stream().limit(4).forEach(System.out::println);
//3,2,2,3
复制代码
sorted
sorted 方法用于对流进行排序。如下代码片断使用 sorted 方法进行排序:
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
numbers.stream().sorted().forEach(System.out::println);
//2,2,3,3,3,5,7
复制代码
distinct
distinct主要用来去重,如下代码片断使用 distinct 对元素进行去重:
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
numbers.stream().distinct().forEach(System.out::println);
//3,2,7,5
复制代码
接下来咱们经过一个例子和一张图,来演示下,当一个Stream前后经过filter、map、sort、limit以及distinct处理后会发生什么。
代码以下:
List<String> strings = Arrays.asList("Hollis", "HollisChuang", "hollis", "Hello", "HelloWorld", "Hollis");
Stream s = strings.stream().filter(string -> string.length()<= 6).map(String::length).sorted().limit(3)
.distinct();
复制代码
过程及每一步获得的结果以下图:
Stream的中间操做获得的结果仍是一个Stream,那么如何把一个Stream转换成咱们须要的类型呢?好比计算出流中元素的个数、将流装换成集合等。这就须要最终操做(terminal operation)
最终操做会消耗流,产生一个最终结果。也就是说,在最终操做以后,不能再次使用流,也不能在使用任何中间操做,不然将抛出异常:
java.lang.IllegalStateException: stream has already been operated upon or closed
复制代码
俗话说,“你永远不会两次踏入同一条河”也正是这个意思。
经常使用的最终操做以下图:
forEach
Stream 提供了方法 'forEach' 来迭代流中的每一个数据。如下代码片断使用 forEach 输出了10个随机数:
Random random = new Random();
random.ints().limit(10).forEach(System.out::println);
复制代码
count
count用来统计流中的元素个数。
List<String> strings = Arrays.asList("Hollis", "HollisChuang", "hollis","Hollis666", "Hello", "HelloWorld", "Hollis");
System.out.println(strings.stream().count());
//7
复制代码
collect
collect就是一个归约操做,能够接受各类作法做为参数,将流中的元素累积成一个汇总结果:
List<String> strings = Arrays.asList("Hollis", "HollisChuang", "hollis","Hollis666", "Hello", "HelloWorld", "Hollis");
strings = strings.stream().filter(string -> string.startsWith("Hollis")).collect(Collectors.toList());
System.out.println(strings);
//Hollis, HollisChuang, Hollis666, Hollis
复制代码
接下来,咱们仍是使用一张图,来演示下,前文的例子中,当一个Stream前后经过filter、map、sort、limit以及distinct处理后会,在分别使用不一样的最终操做能够获得怎样的结果:
下图,展现了文中介绍的全部操做的位置、输入、输出以及使用一个案例展现了其结果。
本文介绍了Java 8中的Stream 的用途,优势等。还接受了Stream的几种用法,分别是Stream建立、中间操做和最终操做。
Stream的建立有两种方式,分别是经过集合类的stream方法、经过Stream的of方法。
Stream的中间操做能够用来处理Stream,中间操做的输入和输出都是Stream,中间操做能够是过滤、转换、排序等。
Stream的最终操做能够将Stream转成其余形式,如计算出流中元素的个数、将流装换成集合、以及元素的遍历等。
GitHub 1.5k Star 的Java工程师成神之路 ,不来了解一下吗?
GitHub 1.5k Star 的Java工程师成神之路 ,真的不来了解一下吗?
GitHub 1.5k Star 的Java工程师成神之路 ,真的肯定不来了解一下吗?