stream 简单使用

  • 生成流
List<String> list = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
//为集合创建串行流。主线程,单线程
List<String> stream = list.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
//并行流。即多个线程同时运行
List<String> parallelStream = list.parallelStream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
  • 简单 for循环
list.stream().forEach(e ->e.setValue(value));
list.forEach(e ->e.setValue(value));
list.forEach(e ->{ ...... });
  • 过滤: filter(T -> boolean)
    list.stream() .filter(过滤条件) .collect(Collectors.toList())
List<X> list = aList.stream()
			.filter(a -> "value".equals(a.getValue()))
			.collect(Collectors.toList());
  • 分组
Map<Object,List<Object>> consInfoGroupMap = list.stream()
						.collect(Collectors.groupingBy(Object::getValue));
//如:名字相同的 List<User>
Map<String, List<User>> consInfoGroupMap = userList.stream()
						.collect(Collectors.groupingBy(User::getName));
//如:名字相同的 Long多少人
Map<String, Long> consInfoGroupMap = userList.stream()
			.collect(Collectors.groupingBy(User::getName,Collectors.counting()));
  • 多级分组
    groupingBy 可以接受一个第二参数实现多级分组:
Map<Integer, Map<T, List<User>>> map = list.stream()
						.collect(groupingBy(User::getAge, groupingBy(...)));
//其中返回的 Map 键为 Integer 类型,
//值为 Map<T, List<Person>> 类型,即参数中 groupBy(...) 返回的类型
  • 根据字段排序 sorted() / sorted((T, T) -> int)
List<Object> items = list().stream()
			.sorted(Comparator.comparing(Object::getValue))
			.collect(Collectors.toList());

//如:根据年龄排序
List<User> items = list().stream()
				.sorted(Comparator.comparing(User::getAge))
				.collect(Collectors.toList());

//如:过滤加排序 全部男性根据age排序
List<User> userList = list.stream()
				.filter(temp -> temp.getSix().equals("男人"))
				.sorted(Comparator.comparing(temp -> temp.getAge()))
				.collect(Collectors.toList());
  • 返回前 n 个元素 limit(long n)
//如:返回前两个user 对象
List<User> userList = list.stream().limit(2).collect(toList());
  • 去除前 n 个元素 skip(long n)
如:去除钱两个User对象后,返回其余 user 对象
List<User> userList = list.stream().skip(2).collect(toList());
  • tips :
    skip(m) 用在limt(n)前面时,先去除前面m个元素再返回剩余元素的前n个元素
    limit(n) 用在skip(m)前面时,先返回前n个元素再在剩余的n个元素中去除m个元素

  • map(T -> R) 获取集合 中对象的value属性的值
    将流中的每一个元素 T 映射为 R(类似类型转换)

List<String> values = list.stream()
			.map(Object::getValue).collect(Collectors.toList());
List<String> values = list.stream()
			.map(x -> x.getValue()).collect(Collectors.toList());
//如:
List<String> names = list.stream()
			.map(User::getName).collect(Collectors.toList());
  • flatMap(T -> Stream)
    将流中的每一个元素 T 映射为一个流,再把每一个流连接成为一个流
List<String> list = new ArrayList<>();
	list.add("aaa,bbb,ccc");
	list.add("ddd,eee,fff");
	list.add("ggg,hhh,iii");
	list = list.stream()
		.map(p -> p.split(","))
		.flatMap(Arrays::stream)
		.collect(toList());

我们的目的是把 List 中每个字符串元素以","分割开,变成一个新的 List。
首先 map 方法分割每个字符串元素,但此时流的类型为 Stream<String[ ]>,因为 split 方法返回的是 String[ ] 类型;所以我们需要使用 flatMap 方法,先使用Arrays::stream将每个 String[ ] 元素变成一个 Stream 流,然后 flatMap 会将每一个流连接成为一个流,最终返回我们需要的 Stream

  • anyMatch(T -> boolean)
    流中是否有一个元素匹配给定的 T -> boolean 条件
    是否存在一个 user 对象的 age 等于 20:
boolean b = list.stream().anyMatch(user -> user .getAge() == 20);
  • allMatch(T -> boolean)
    流中是否所有元素都匹配给定的 T -> boolean 条件

  • noneMatch(T -> boolean)
    流中是否没有元素匹配给定的 T -> boolean 条件

  • findAny() 和 findFirst()

findAny():找到其中一个元素 
使用 stream() 时找到的是第一个元素;
parallelStream() 并行时找到的是其中一个元素
findFirst():找到第一个元素 
值得注意的是,这两个方法返回的是一个 Optional<T> 对象,它是一个容器类,能代表一个值存在或不存在
  • reduce((T, T) -> T) 和 reduce(T, (T, T) -> T)
    用于组合流中的元素,如求和,求积,求最大值等
    计算年龄总和:
int sum = list.stream().map(User::getAge).reduce(0, (a, b) -> a + b);
//相同写法:
int sum = list.stream().map(User::getAge).reduce(0, Integer::sum);
//其中,reduce 第一个参数 0 代表起始值为 0,
//lambda (a, b) -> a + b 即将两值相加产生一个新值
  • 计算乘积
//同样地,计算年龄总乘积
int sum = list.stream().map(User::getAge).reduce(1, (a, b) -> a * b);
//或者
Optional<Integer> sum = list.stream()
				.map(User::getAge).reduce(Integer::sum);
//即不接受任何起始值,但因为没有初始值
//需要考虑结果可能不存在的情况,因此返回的是 Optional 类型
  • count()
    返回流中元素个数,结果为 long 类型
  • collect()
    收集方法,我们很常用的是 collect(toList()),当然还有 collect(toSet()) 等,参数是一个收集器接口
  • joining 连接字符串
    也是一个比较常用的方法,对流里面的字符串元素进行连接,其底层实现用的是专门用于字符串连接的 StringBuilder
//将User 的getName值 进行连接
String s = list.stream().map(User::getName).collect(joining());
//将User 的getName值 用","进行连接
String s = list.stream().map(User::getName).collect(joining(","));
//结果:name1,name2,name3

joining 还有一个重载方法:

String s = list.stream()
		.map(User::getName).collect(joining(" and ", "Today ", " play games."));
//结果:Today name1 and name2 and name3 play games.
//即 Today 放开头,play games. 放结尾,and 在中间连接各个字符串
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值