1 前言


Stream是一个来自数据源的元素队列并支持聚合操作,其中具有以下特性:

  • Stream只负责计算,不存储任何元素,元素是特定类型的对象,形成一个队列

  • 数据源可以实集合、数组、I/O channel、generator等

  • 聚合操作有类似SQL的:filter、map、match、sorted等操作

  • Stream流的执行类似于懒加载,用户使用时才执行相应操作

  • 可消费性;Stream只能被消费一次,被消费后需要重新生成

本文总结了部分在日常开发中经常接触到的一些Stream流相关的方法,不足之处或有错误欢迎留评,总结的几个方法如下:

  • void forEach() : 迭代流中的数据

  • Stream map() : 用于映射每个元素到对应的结果

  • Stream filter() : 条件过滤器

  • Stream sorted() : 排序

  • R collect() : 流数据 -> 集合/数组

  • 待补充...

2 forEach()


forEach()源码:

void forEach(Consumer<!--? super T--> action);

Stream().forEach() : 迭代流中的数据

forEach() 的返回类型为void,不会产生新的流

举个栗子:

public void testForEach() {
/**
* 使用forEach()内部迭代
* ints()表示整数类型
* limit()表示限制流个数(次数)
*/
Random random = new Random();
random.ints().limit(10).forEach(System.out::println);
}

运行结果:

再举个灵活一点的栗子:

public void testForEach() {
/**
* 使用forEach()转换集合类型,如List->Map
*/
AtomicInteger i = new AtomicInteger();//原子类型
Map<Integer,String> map = new HashMap<>();
List<String> list = new ArrayList<>(Arrays.asList("Hello",",","world"));
list.stream().forEach(s->{
map.put(i.getAndIncrement(),s);
});
}

对于forEach()方法在本人日常开发中常用于:

  • 使用内循环对集合进行遍历

  • 使用foreach方法将List转为Map形式

3 map()


map()源码:

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

Stream().map() 用于映射每个元素到对应的结果

返回类型为Stream,map()会产生新的流并返回

举个栗子:

public void testMap(){
/**
* map()获取list每个元素的平方值
* distinct()去重操作
* collect()将map()产生的新的流转为List类型
*/
List<Integer> list = Arrays.asList(1,2,3);
list.stream().map(num -> num * num)
.distinct()
.collect(Collectors.toList())
.forEach(System.out::println);
}

4 filter()


filter()源码:

Stream<T> filter(Predicate<? super T> predicate);

Stream().filter()为条件过滤器

举个栗子:

public void testFilter(){
/**
* filter()过滤空字符串
* count()统计符合条件的个数,返回类型long
*/
List<String> list = new ArrayList<>(Arrays.asList("ab","","abc","","acd"));
long count = list.stream()
.filter(str -> str.isEmpty())
.count();
}

5 sorted()


sorted()源码:

Stream<T> sorted();
Stream<T> sorted(Comparator<? super T> comparator);

Stream支持两种方式的排序:

  • 无参方法默认为自然排序

  • sorted(Comparator comp) 按自定义比较器进行排序

仍然是举个栗子:

1)无参方法

public void testSorted(){
/**
* sort()无参默认为自然排序
* 返回类型Stream 会产生新的流
*/
List<String> list = new ArrayList<>(Arrays.asList("aaa","ccc","bbb"));
list.stream().sorted().forEach(System.out::println);
}

执行结果:

2)带参方法(User类由name和age组成)

  • 先比较年龄,按从小到大排序

  • 若年龄相等,则按性名自然排序

public void testSorted(){
/**
* sort(Comparator comp)按自定义比较器进行排序
* 返回类型同样是Stream 会产生新的流
*/
List<User> userList = new ArrayList<>(Arrays.asList(
new User("zhangsan",22),
new User("wangwu",22),
new User("badao",32),
new User("kongfu",16)
));
Stream<User> sorted = userList.stream().sorted((x, y) -> {
if (x.getAge() == y.getAge()) { // 使用流中的序列两两进行比较
return x.getName().compareTo(y.getName());
} else {
return x.getAge() - y.getAge();//顺序
// y.getAge() - x.getAge() 为逆序
}
});
sorted.forEach(System.out::println);
}

执行结果:

6 collect()


collect()源码:

<R> R collect(Supplier<R> supplier,
BiConsumer<R, ? super T> accumulator,
BiConsumer<R, R> combiner);

stream().collect() 由三个参数构成 :

  1. Supplier 生产者,返回最终结果
  2. BiConsumer<R, ? super T> accumulator,累加器 :

    其中 R 为要返回的集合, ? super T 为遍历过程中的每个参数,相当于add操作
  3. BiConsumer<R,R> combiner,合并器 :

    有并行流时才会使用,相当于将第二部操作形成的list添加到最终的list,addAll操作

举个栗子:

1)new()

public void testCollect(){

    Stream<String> stream = Stream.of("hello","world","hello,world");

    // new()
List<String> list = stream.collect(Collectors.toList());//List
// 指定集合类型,如ArrayList
ArrayList<String> arrayList = stream.collect(Collectors.toCollection(ArrayList::new));
//Set
stream.collect(Collectors.toSet());
// 指定HashSet
HashSet<String> hashSet = stream.collect(Collectors.toCollection(HashSet::new));
// 拼接字符串
String str = stream.collect(Collectors.joining());

2)new() -> add() -> addAll()

public void testCollect(){
/**
* 参数传递行为相当于: new() -> add() -> addAll()
*/
Stream<String> stream = Stream.of("hello","world","hello,world");
// new() -> add() -> addAll()完整演示
HashMap<String,String> map = stream.collect(HashMap::new,(x,y)->{
x.put(y,y); // x 为集合,y 为当前遍历元素,以当前遍历元素作为kv
},HashMap::putAll);
map.forEach((x,y)->{
System.out.println(x+" : "+y);
});

执行结果:

Java-Stream流方法学习及总结的更多相关文章

  1. 一文带你入门Java Stream流,太强了

    两个星期以前,就有读者强烈要求我写一篇 Java Stream 流的文章,我说市面上不是已经有很多了吗,结果你猜他怎么说:"就想看你写的啊!"你看你看,多么苍白的喜欢啊.那就&qu ...

  2. 全面吃透JAVA Stream流操作,让代码更加的优雅

    全面吃透JAVA Stream流操作,让代码更加的优雅 在JAVA中,涉及到对数组.Collection等集合类中的元素进行操作的时候,通常会通过循环的方式进行逐个处理,或者使用Stream的方式进行 ...

  3. Java8 Stream流方法

    流是Java API的新成员,它允许以声明性方式处理数据集合(通过查询语句来表达,而不是临时编写一个实现).就现在来说,可以把它们看成遍历数据集的高级迭代器.此外,流还可以透明地并行处理,无需写任何多 ...

  4. Java Stream 流如何进行合并操作

    1. 前言 Java Stream Api 提供了很多有用的 Api 让我们很方便将集合或者多个同类型的元素转换为流进行操作.今天我们来看看如何合并 Stream 流. 2. Stream 流的合并 ...

  5. Java Stream 流(JDK 8 新特性)

    什么是 Steam Java 8 中新增了 Stream(流)来简化集合类的使用,Stream 本质上是个接口,接口中定义了很多对 Stream 对象的操作. 我们知道,Java 中 List 和 S ...

  6. Java | Stream流、泛型、多线程 | 整理自用

    1.lambda 表达式 lambda 的延迟执行 可以对程序进行优化,尤其是使用 if {} else {} 条件判断,先判断条件是否成立,再传入计算好的参数. functionName( para ...

  7. 深度掌握 Java Stream 流操作,让你的代码高出一个逼格!

    概念 Stream将要处理的元素集合看作一种流,在流的过程中,借助Stream API对流中的元素进行操作,比如:筛选.排序.聚合等. Stream 的操作符大体上分为两种:中间操作符和终止操作符 中 ...

  8. Java Stream流的使用

    流相关的方法可以分为三种类型,分别是:获取Stream流.中间方法.终结方法.中间方法会返回当前流,可以方便的进行链式调用. 流不可重复使用,否则会报错: java.lang.IllegalState ...

  9. Java数组合并方法学习。

    参考博客: https://blog.csdn.net/liu_005/article/details/72760392 https://blog.csdn.net/jaycee110905/arti ...

随机推荐

  1. Pandas高级教程之:plot画图详解

    目录 简介 基础画图 其他图像 bar stacked bar barh Histograms box Area Scatter Hexagonal bin Pie 在画图中处理NaN数据 其他作图工 ...

  2. ps 合并两张图片

    1.ps 打开第一张图片,2.打开另一张图片为图层.3.选中图层,创建蒙版: 4.点击蒙版+按Alt键,打开蒙版:5.打开蒙版后选中渐变工具,途中黑色为不显示区域,(注意渐变模式要改为正常):6.调整 ...

  3. 【知识点】C++的日志框架

    常用的 C++ 日志框架 一.日志框架 一个经过专门设计的实用程序,用于规范应用程序的日志记录过程,就是日志框架.   日志框架可以自己编写(需要一定的能力哦),也可以由第三方(例如:log4cplu ...

  4. centos 8.3系统调优参数配置

    临时设置 最大虚拟内存 [root@Sonnarqube-dev ~]# sysctl -w vm.max_map_count=262144 执行结果 vm.max_map_count = 26214 ...

  5. 面试题三:MySQL

    MySQL有哪些存储引擎? MyISAM.InnoDB.CSV.Memory等 MyISAM和InnoDB比较: InnoDB MyISAM 事务 支持 不支持 存储限制 64TB 无 锁粒度 行锁 ...

  6. java:编写jar包加密工具,防止反编译

    懒人方案 网盘: 链接:https://pan.baidu.com/s/1x4OB1IF2HZGgtLhd1Kr_AQ提取码:glx7 网盘内是已生成可用工具,下载可以直接使用,使用前看一下READ. ...

  7. flask的常规使用二

    一.路由(router) 路由指定了url 到函数之间的一个映射关系. url ---> flask框架拿到url 的路径部分和路由中的内容进行匹配,如果匹配成功了则执行对应的函数.如果没有找到 ...

  8. 架构之:REST和RESTful

    目录 简介 REST REST和RESTful API REST架构的基本原则 Uniform interface统一的接口 Client–server 客户端和服务器端独立 Stateless无状态 ...

  9. Linux | Shell流程控制语句

    流程控制语句 简单的Shell 脚本还不能满足我们日常工作的需要要,因为他不能批量的帮我们完成工作,所以Shell引入了 if.for.while.case 4种流程控制语句来帮助我们完成工作. if ...

  10. 「AGC027D」Modulo Matrix

    「AGC027D」Modulo Matrix 传送门 神仙构造题. 首先考虑一个非常自然的思路,我们把棋盘黑白染色后会变成一个二分图,黑色棋子只会与白色棋子相邻. 也就是说,我们可以将二分图的一部随便 ...