- 首页 > it技术 > >
- stream:
- 是数据渠道,用于操作数据源(数组,集合等.)所产生的元素序列
- 集合讲的是数据,流讲的是计算.
- 并行: parallel
- 注意:
- stram 自己不会存储元素.
- stream 不会改变源对象,相反 他们会返回一个持有结果的新stream.
- stream 操作是延迟执行的,这意味着他们会等到需要结果的时候才执行.
- 使用步骤:
- 1.创建stream
- 2.中间操作
- 3.终止操作
- 注意:中间操作 不会执行任何操作,只有在终止操作的时候才会一次性执行.
- 多个中间操作可以连接起来形成一个流水线,除非流水线上出发终止操作,否则中间操作不会执行任何处理.而在终止操作时一次性全部处理.称为 "惰性求值".
-
public static void main(String[] args) {
//可以通过Collection系列集合提供的stream() 串行 或 parallelStream() 并行
List list = new ArrayList<>();
Stream stream = list.stream();
//通过Arrays中的静态方法stream()获取 数组流
LoginRequest[] loginRequests = new LoginRequest[10];
Stream stream1 = Arrays.stream(loginRequests);
//通过stream类中的静态方法of()
Stream aa = Stream.of("aa");
//创建 无限流
//迭代
Stream iterate = Stream.iterate(0, (x) -> x + 2);
//iterate.limit(10) 就是中间操作
//forEach(System.out::println) 就是终止操作
iterate.limit(10).forEach(System.out::println);
}
【java 1.8 Stream】
- 中间操作:
- 筛选与切片
- filter接收lambda, 从六中排除某些元素
- limit截断流.使其元素不超过给定数量
- skip(n) 跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个,则返回一个空流,与limit互补
- distinct 筛选(去重),通过流所生成元素的hashCode()和equals()去除重复元素
- filter筛选:
-
static List loginRequests = Arrays.asList(
new LoginRequest("张三", "1111", "11"),
new LoginRequest("李四", "2222", "22"),
new LoginRequest("王五", "3333", "33"),
new LoginRequest("赵六", "6666", "66")
);
/**
* @Description: filter筛选
* @Param: [args]
* @return: void
* @Author: 单人影
* @Date: 2019/12/8 0008 15:59
*/
public static void main(String[] args) {
Stream loginRequestStream = loginRequests.stream().filter((e) -> "22".equals(e.getAge()));
loginRequestStream.forEach(System.out::println);
}
- limit截断:
-
static List loginRequests = Arrays.asList(
new LoginRequest("张三", "1111", "11"),
new LoginRequest("李四", "2222", "22"),
new LoginRequest("王五", "3333", "33"),
new LoginRequest("赵六", "6666", "66")
);
/**
* @Description: limit截断
* @Param: [args]
* @return: void
* @Author: 单人影
* @Date: 2019/12/8 0008 15:59
*/
public static void main(String[] args) {
loginRequests.stream()
.filter((e) -> Integer.valueOf(e.getAge()) > 11)
.limit(2)
.forEach(System.out::println);
}控制台:
LoginRequest{userName='李四', passWord='2222', age='22'}
LoginRequest{userName='王五', passWord='3333', age='33'}
- skip 跳过:
-
static List loginRequests = Arrays.asList(
new LoginRequest("张三", "1111", "11"),
new LoginRequest("李四", "2222", "22"),
new LoginRequest("王五", "3333", "33"),
new LoginRequest("赵六", "6666", "66")
);
/**
* @Description: skip 跳过
* @Param: [args]
* @return: void
* @Author: 单人影
* @Date: 2019/12/8 0008 15:59
*/
public static void main(String[] args) {
loginRequests.stream()
.filter((e) -> Integer.valueOf(e.getAge()) > 11)
.skip(2)
.forEach(System.out::println);
}控制台:
LoginRequest{userName='赵六', passWord='6666', age='66'}
- distinct 去重
-
static List loginRequests = Arrays.asList(
new LoginRequest("张三", "1111", "11"),
new LoginRequest("张三", "1111", "11"),
new LoginRequest("张三", "1111", "11"),
new LoginRequest("李四", "2222", "22"),
new LoginRequest("王五", "3333", "33"),
new LoginRequest("赵六", "6666", "66")
);
/**
* @Description: distinct 去重
* @Param: [args]
* @return: void
* @Author: 单人影
* @Date: 2019/12/8 0008 15:59
*/
public static void main(String[] args) {
loginRequests.stream()
.filter((e) -> Integer.valueOf(e.getAge()) > 1)
.distinct()
.forEach(System.out::println);
}要重写对象的equals和hashCode方法.
控制台:
LoginRequest{userName='张三', passWord='1111', age='11'}
LoginRequest{userName='李四', passWord='2222', age='22'}
LoginRequest{userName='王五', passWord='3333', age='33'}
LoginRequest{userName='赵六', passWord='6666', age='66'}
- 映射:
- map 接受lambda,讲元素转成其他形式或提取信息,接受一个函数作为参数,该函数会被应用到每一个元素上,并将其映射成一个新的元素.
- flagMap 接收一个函数作为参数,将流中的每一个值都转换成另一个流,然后把所有的流了解成一个流.
-
/**
* @Description: 映射 map
* @Param: [args]
* @return: void
* @Author: 单人影
* @Date: 2019/12/8 0008 15:59
*/
public static void main(String[] args) {
List list = Arrays.asList("aaa", "bbb", "ccc", "ddd");
list.stream().map((str) -> str.toUpperCase()).forEach(System.out::println);
}控制台:
AAA
BBB
CCC
DDD/**
* @Description: 映射 flatMap
* @Param: [args]
* @return: void
* @Author: 单人影
* @Date: 2019/12/8 0008 15:59
*/
public static void main(String[] args) {
list.stream().map((str) -> str.toUpperCase()).forEach(System.out::println);
System.out.println("----------------------------------");
//正常的map取值
Stream> streamStream = list.stream().map(Test::filter);
//使用flatMap 都放到flagMap中
Stream characterStream = list.stream().flatMap(Test::filter);
characterStream.forEach(System.out::println);
}public static Stream filter(String string) {
List list = new ArrayList();
for (Character character : string.toCharArray()) {
list.add(character);
}
return list.stream();
}总结:map相当于把一个个流加到map这个大流中.
flatMap 相当于把流中的一个个元素加到flatMap流中
- 排序:
- sorted()自然排序
- sorted(Comparator com) 定制排序
-
static List loginRequests = Arrays.asList(
new LoginRequest("张三", "1111", "11"),
new LoginRequest("张三1", "1113", "11"),
new LoginRequest("张三2", "1112", "11"),
new LoginRequest("李四", "2222", "22"),
new LoginRequest("王五", "3333", "33"),
new LoginRequest("赵六", "6666", "66")
);
static List list = Arrays.asList("aaa", "ccc", "ddd", "bbb");
/**
* @Description: 排序 sorted
* @Param: [args]
* @return: void
* @Author: 单人影
* @Date: 2019/12/8 0008 15:59
*/
public static void main(String[] args) {
list.stream().sorted().forEach(System.out::println);
//控制台 aaa bbb ccc ddd
loginRequests.stream().sorted((x, y) -> {
//年龄相同 比密码
if (x.getAge().equals(y.getAge())) {
return x.getPassWord().compareTo(y.getPassWord());
} else {
//直接比年龄
return Integer.valueOf(x.getAge()).compareTo(Integer.valueOf(y.getAge()));
//倒叙 return -Integer.valueOf(x.getAge()).compareTo(Integer.valueOf(y.getAge()));
}
}
).forEach(System.out::println);
}控制台:
LoginRequest{userName='张三', passWord='1111', age='11'}
LoginRequest{userName='张三2', passWord='1112', age='11'}
LoginRequest{userName='张三1', passWord='1113', age='11'}
LoginRequest{userName='李四', passWord='2222', age='22'}
LoginRequest{userName='王五', passWord='3333', age='33'}
LoginRequest{userName='赵六', passWord='6666', age='66'}
- 终止:
- 查找与匹配:
- allMatch 检查是否匹配所有元素
- anyMatch 检查是否至少匹配一个元素
- noneMatch 检查是否没有匹配的所有元素
- findFirst 返回第一个元素
- finaAny 返回当前流中的任意元素
- count 返回流中元素的总个数
- max 返回流中最大值
- min 返回流中最小值
-
static List loginRequests = Arrays.asList(
new LoginRequest("张三", "1111", "11"),
new LoginRequest("张三1", "1113", "11"),
new LoginRequest("张三2", "1112", "11"),
new LoginRequest("李四", "2222", "22"),
new LoginRequest("王五", "3333", "33"),
new LoginRequest("赵六", "6666", "66")
);
/**
* @Description: 查找匹配
* @Param: [args]
* @return: void
* @Author: 单人影
* @Date: 2019/12/8 0008 15:59
*/
public static void main(String[] args) {
boolean b = loginRequests.stream().allMatch((x) -> x.getPassWord().equals("111111"));
System.out.println(b);
//其余的匹配用法基本相同//findFirst
Optional optional = loginRequests.stream().sorted((x, y) -> x.getAge().compareTo(y.getAge())).findFirst();
//Optional是为了放置空指针 如果为空就用orElse()括号里面的.
LoginRequest loginRequest1 = new LoginRequest("111", "222", "333");
LoginRequest loginRequest = optional.orElse(loginRequest1);
System.out.println(loginRequest.toString());
}控制台:
false
LoginRequest{userName='张三', passWord='1111', age='11'}
- 归约 reduce(T identity,BinaryOperator ) /reduct(BinaryOperator)可以将流中元素反复结合起来,得到一个值.
-
/**
* @Description: 归约 reduce
* @Param: [args]
* @return: void
* @Author: 单人影
* @Date: 2019/12/8 0008 15:59
*/
public static void main(String[] args) {
List list = Arrays.asList(1, 2, 3, 4, 5);
Integer reduce = list.stream().reduce(0, (x, y) -> x + y);
System.out.println(reduce);
System.out.println("================================");
//有可能返回为空的都是Optional ,因为上面指定了起始值.不可能为空.
Optional reduce1 = loginRequests.stream().map(LoginRequest::getUserName).reduce((x, y) -> x += (y));
System.out.println(reduce1);
}控制台:
15
================================
Optional[张三张三1张三2李四王五赵六]
- 收集: collect 将流转换为其他形式,接受一个collector接口的实现,用于给stream中元素做汇总的方法. (分组)
-
static List loginRequests = Arrays.asList(
new LoginRequest("张三", "1111", "11"),
new LoginRequest("张三1", "1113", "11"),
new LoginRequest("张三2", "1112", "11"),
new LoginRequest("李四", "2222", "22"),
new LoginRequest("王五", "3333", "33"),
new LoginRequest("赵六", "6666", "66")
);
static List list = Arrays.asList("aaa", "ccc", "ddd", "bbb");
/**
* @Description: 收集 collect
* @Param: [args]
* @return: void
* @Author: 单人影
* @Date: 2019/12/8 0008 15:59
*/
public static void main(String[] args) {
List collect = loginRequests.stream().map(LoginRequest::getUserName).collect(Collectors.toList());
System.out.println(collect.toString());
Set collects= loginRequests.stream().map(LoginRequest::getAge).collect(Collectors.toSet());
System.out.println(collects.toString());
//分组 groupingBy还可以多级分组
Map> collect1 = loginRequests.stream().collect(Collectors.groupingBy(LoginRequest::getAge));
System.out.println(collect1.toString());
//还可以分区.true一个区 false一个区 Collectors.partitioningBy
//连接 Collectors.join()可以写成join(",") 逗号拼接}控制台:
[张三, 张三1, 张三2, 李四, 王五, 赵六]
[11, 22, 33, 66]
{66=[LoginRequest{userName='赵六', passWord='6666', age='66'}], 33=[LoginRequest{userName='王五', passWord='3333', age='33'}], 22=[LoginRequest{userName='李四', passWord='2222', age='22'}], 11=[LoginRequest{userName='张三', passWord='1111', age='11'}, LoginRequest{userName='张三1', passWord='1113', age='11'}, LoginRequest{userName='张三2', passWord='1112', age='11'}]}
- 使用示例:
-
list累加
BigDecimal allAssets = tradeBalanceCrmList.stream().filter(item -> item.getTotalProfit() != null).map(TradeBalanceCrmDto::getTotalProfit).reduce(BigDecimal.ZERO, BigDecimal::add);
分组
Map> productTypeGroupBy = tradeBalanceCrmList.stream().filter(item -> StringUtils.isNotEmpty(item.getProductType())).collect(Collectors.groupingBy(TradeBalanceCrmDto::getProductType));
遍历
for (String key : productTypeGroupBy.keySet()) {
if (ProductTypeEnum.PUBLICFUND.getCode().equals(key)) {
publicList.addAll(productTypeGroupBy.get(key));
log.debug("公募:{},value:{}", productTypeGroupBy.get(key));
} else if (ProductTypeEnum.PRIVATEFUND.getCode().equals(key)) {
privateList.addAll(productTypeGroupBy.get(key));
log.debug("似募:{},value:{}", productTypeGroupBy.get(key));
}
}排序:
Collections.sort(tradeAppFlowDtos, (o1, o2) -> o2.getAcceptTime().compareTo(o1.getAcceptTime()));
如果要按照升序排序,
则o1 小于o2,返回-1(负数),相等返回0,01大于02返回1(正数)
如果要按照降序排序
则o1 小于o2,返回1(正数),相等返回0,01大于02返回-1(负数)去除为空字段.返回list
List collect = custManagerInfos.stream().filter((item) -> StringUtils.isNotEmpty(item.getFundManagerCode())).collect(Collectors.toList());
- 双层for循环:
-
List tradeBalanceCrmDtos = tradeBalanceCrmExtendMapper.selectByConditionByCustId(custId);
if (CollectionUtils.isEmpty(tradeBalanceCrmDtos)) {
return tradeBalanceCrmDtos;
}
List list = new ArrayList<>();
TradeBalanceCrmDto tradeBalanceCrmDtoResult = null;
for (TradeBalanceCrmDto tradeBalanceCrmDto : tradeBalanceCrmDtos) {
boolean flag = list.stream().anyMatch(item -> item.getFundCode().equals(tradeBalanceCrmDto.getFundCode()));
if (flag) {
continue;
}
tradeBalanceCrmDtoResult = new TradeBalanceCrmDto();
BeanUtils.copyProperties(tradeBalanceCrmDto, tradeBalanceCrmDtoResult);
List collect = tradeBalanceCrmDtos.stream().filter((item) -> tradeBalanceCrmDto.getFundCode().equals(item.getFundCode())).collect(Collectors.toList());
log.debug("归集的List为:{}", collect.toString());
tradeBalanceCrmDtoResult.setFundAsset(collect.stream().filter((item) -> item.getFundAsset() != null).map(TradeBalanceCrmDto::getFundAsset).reduce(BigDecimal.ZERO, (x, y) -> x.add(y)));
tradeBalanceCrmDtoResult.setTotalBala(collect.stream().filter((item) -> item.getTotalBala() != null).map(TradeBalanceCrmDto::getTotalBala).reduce(BigDecimal.ZERO, (x, y) -> x.add(y)));
tradeBalanceCrmDtoResult.setAvailBala(collect.stream().filter((item) -> item.getAvailBala() != null).map(TradeBalanceCrmDto::getAvailBala).reduce(BigDecimal.ZERO, (x, y) -> x.add(y)));
tradeBalanceCrmDtoResult.setTotalProfit(collect.stream().filter((item) -> item.getTotalProfit() != null).map(TradeBalanceCrmDto::getTotalProfit).reduce(BigDecimal.ZERO, (x, y) -> x.add(y)));
list.add(tradeBalanceCrmDtoResult);
}
- 常用示例:
-
//过滤不为空的list
List collect = custManagerInfos.stream().filter((item) ->
StringUtils.isNotEmpty(item.getFundManagerCode())).collect(Collectors.toList());
//非空 分组
Map> registarCodeMap = list.stream().filter(item -> StringUtils.isNotEmpty(item.getRegistrarCode())).collect(Collectors.groupingBy(TransferListVo::getRegistrarCode));
//非空 累加
BigDecimal allAssets = tradeBalanceCrmList.stream().filter(item -> item.getTotalProfit() != null).map(TradeBalanceCrmDto::getTotalProfit).reduce(BigDecimal.ZERO, BigDecimal::add);
推荐阅读