一、java8新特性
我们先来看看java里面怎么定义的Stream的:
- Stream是元素的集合,这点让Stream看起来用写类似Iterator;
- 可以支持顺序和并行的对原Stream进行汇聚的操作
可以把Stream当成一个高级版本的Iterator。原始版本的Iterator,用户只能一个一个遍历元素并对其执行某些操作;高级版本的Stream,用户只要给出需要对其包含的元素执行什么操作,比如“过滤掉长度大于10的字符串”、“获取每个字符串的首字母”等,具体这些操作如何应用到每个元素上,就给Stream就好了!
Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。
元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。
二、什么是Stream?
Stream(流)是一个来自数据源的元素队列并支持聚合操作
1.元素是特定的对象,形成一个队列。java中的Stream并不会存储元素,而是按需计算。
2.数据源流的来源。可以是集合,数组,IO/ channel,产生器generator等。
3.聚合操作 类似SQL语句一样的操作,比如filter、map、reduce、find、match、sorted等。
和以前的Collection操作不同, Stream操作还有两个基础的特征:
1.Pipelining: 中间操作都会返回流对象本身。这样多个操作可以串联成一个管道,如同流式风格(fluent style)。这样做可以对操作进行优化。比如延迟执行(laziness)和短路(short-circuiting)。
2.内部迭代:以前对集合遍历都是通过Iterator或者For-Each的方式,显示的在集合外部进行迭代,这就叫做外部迭代。
生成流
在 Java 8 中, 集合接口有两个方法来生成流:
stream() − 为集合创建串行流。
parallelStream() − 为集合创建并行流。
三、常用的操作符
filter: 用于通过设计的条件过滤出元素
/**
* 功能描述:过滤掉字符为空的元素
*/
List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
System.out.println(filtered);
distinct: 返回一个元素各异(根据流所生成的元素的hashCode和equals方法实现)的流
/**
* 功能描述:distinct 去除相同的元素
* @return:
*/
List<String> strings = Arrays.asList("abc", "bc", "bc", "efg", "abcd","", "jkl");
List<String> distincted = strings.stream().distinct().collect(Collectors.toList());
System.out.println(distincted);
**limit:**会返回一个不超过给定长度的流
/**
* 功能描述:
* @return:void
*/
List<String> strings = Arrays.asList("abc", "bc", "bc", "efg", "abcd","", "jkl");
List<String> limited = strings.stream().limit(2).collect(Collectors.toList());
System.out.println(limited);
skip: 会返回除去前n个元素的其他所有元素
/**
* 功能描述:
*/
List strings = Arrays.asList(“abc”, “bc”, “bc”, “efg”, “abcd”, “”, “jkl”);
List skipped = strings.stream().skip(2).collect(Collectors.toList());
System.out.println(skipped);
map: 接受一个函数作为参数。这个函数会被应用到每个元素上,并将其映射成一个新的元素(使用映射一词,是因为它和转换类相似,但其中的细微差别在于它是“创建一个新版本而不是去修改”)
/**
* 功能描述:对流中的所有元素做处理
*/
List<String> strings = Arrays.asList("abc", "bc", "bc", "efg", "abcd", "", "jkl");
List<String> mapped = strings.stream().map(str -> str.concat("_prefix")).collect(Collectors.toList());
System.out.println(mapped);
sorted: 返回排序后的流
/**
* 功能描述:
*/
List<String> strings = Arrays.asList("abc", "bc", "bc", "efg", "abcd", "", "jkl");
List<String> sorted = strings.stream().sorted().collect(Collectors.toList());
System.out.println(sorted);
四、常用终止符
anyMatch: 检查是否至少匹配一个元素,返回boolean
/**
* 功能描述:
*/
List<String> strings = Arrays.asList("abc", "bc", "bc", "efg", "abcd", "", "jkl");
boolean bc = strings.stream().allMatch(s -> s.contains("bc"));
System.out.println(bc);
allMatch: 检查是否配置所有元素,返回boolean
/**
* 功能描述:
*/
List<String> strings = Arrays.asList("abc", "bc", "bc", "efg", "abcd", "", "jkl");
boolean bc = strings.stream().allMatch(s -> s.contains("q"));
System.out.println(bc);
noneMatch: 检查是否没有匹配所有元素,返回boolean
/**
* 功能描述:
*/
List<String> strings = Arrays.asList("abc", "bc", "bc", "efg", "abcd", "", "jkl");
boolean bc = strings.stream().noneMatch(s -> s.contains("q"));
System.out.println(bc);
forEach: 循环遍历集合中的元素
List<String> strings = Arrays.asList("abc", "bc", "bc", "efg", "abcd", "e", "jkl");
strings.stream().forEach(System.out::println);
collect: 收集器,将流转换为其他形式:list\set\map
/**
* 功能描述
*/
List<String> strings = Arrays.asList("abc", "bc", "bc", "efg", "abcd", "e", "jkl");
Set<String> collect = strings.stream().collect(Collectors.toSet());
System.out.println(collect);
System.out.println("========");
Map<String, Object> collect1 = strings.stream().collect(Collectors.toMap(v -> v, v ->v, (oldvalue, newvalue) -> newvalue));
System.out.println(collect1);
reduce: 可以将流中元素反复结合起来,得到一个值
/**
* 功能描述
*/
List<String> strings = Arrays.asList("abc", "bc", "bc", "efg", "abcd", "e", "jkl");
Optional<String> reduce = strings.stream().reduce((acc, item) -> {
return acc + item;
});
if(reduce.isPresent()) {
System.out.println(reduce);
}