挖土小能手无广告
90.22MB · 2025-10-16
Java 8 中的 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作(aggregate operation),或者大批量数据操作
Stream 可以并行化操作,迭代器只能命令式地、串行化操作。顾名思义,当使用串行方式去遍历时,每个 item 读完后再读下一个 item。而使用并行去遍历时,数据会被分成多个段,其中每一个都在不同的线程中处理,然后将结果一起输出。Stream 的并行操作依赖于 Java7 中引入的 Fork/Join 框架(JSR166y)来拆分任务和加速处理过程。
构造流的几种常见方法
// 1. Individual values Stream stream = Stream.of("a", "b", "c"); // 2. Arrays String [] strArray = new String[] {"a", "b", "c"}; stream = Stream.of(strArray); stream = Arrays.stream(strArray); // 3. Collections List<String> list = Arrays.asList(strArray); stream = list.stream(); |
需要注意的是,对于基本数值型,目前有三种对应的包装类型 Stream:
IntStream、LongStream、DoubleStream。当然我们也可以用 Stream<Integer>、Stream<Long> >、Stream<Double>,但是 boxing 和 unboxing 会很耗时,所以特别为这三种基本数值型提供了对应的Stream
数值流的构造
IntStream.of(new int[]{1, 2, 3}).forEach(System.out::println);
IntStream.range(1, 3).forEach(System.out::println);
IntStream.rangeClosed(1, 3).forEach(System.out::println);
流转换为其它数据结构
// 1. Array
String[] strArray1 = stream.toArray(String[]::new);
// 2. Collection
List<String> list1 = stream.collect(Collectors.toList());
List<String> list2 = stream.collect(Collectors.toCollection(ArrayList::new));
Set set1 = stream.collect(Collectors.toSet());
Stack stack1 = stream.collect(Collectors.toCollection(Stack::new));
// 3. String
String str = stream.collect(Collectors.joining()).toString();
一个 Stream 只可以使用一次,上面的代码为了简洁而重复使用了数次。
接下来,当把一个数据结构包装成 Stream 后,就要开始对里面的元素进行各类操作了。常见的操作可以归类如下。
它的作用就是把 inputStream 的每一个元素,映射成 outputStream 的另外一个元素。
转换大写(把所有的单词转换为大写。):
List<String> output = wordList.stream().map(String::toUpperCase).collect(Collectors.toList());
转为平方数:
List<Integer> nums = Arrays.asList(1, 2, 3, 4);
List<Integer> squareNums = nums.stream().map(n -> n * n).collect(Collectors.toList());
抽取对象中所有的id的集合
List<Long> idList = AList.stream.map(A::getId).collect(Collectors.toList());
map 生成的是个 1:1 映射,每个输入元素,都按照规则转换成为另外一个元素。还有一些场景,是一对多映射关系的,这时需要 flatMap。
Stream<List<Integer>> inputStream = Stream.of(
Arrays.asList(1),
Arrays.asList(2, 3),
Arrays.asList(4, 5, 6)
);
Stream<Integer> outputStream = inputStream.flatMap((childList) -> childList.stream());
filter 对原始 Stream 进行某项测试,通过测试的元素被留下来生成一个新 Stream。
留下偶数
Integer[] sixNums = {1, 2, 3, 4, 5, 6};
Integer[] evens =Stream.of(sixNums).filter(n -> n%2 == 0).toArray(Integer[]::new);
经过条件“被 2 整除”的 filter,剩下的数字为 {2, 4, 6}。
查找集合中的第一个对象
Optional<A> firstA= AList.stream() .filter(a -> "hanmeimei".equals(a.getUserName())) .findFirst();
获取符合指定条件的集合
List<A> firstA= AList.stream() .filter(a -> "hanmeimei".equals(a.getUserName())) .collect(Collectors.toList());
筛选+排序+取值成新的list
List<Integer> transactionsIds = transactions.parallelStream().
filter(t -> t.getType() == Transaction.GROCERY).
sorted(comparing(Transaction::getValue).reversed()).
map(Transaction::getId).
collect(toList());
list.stream().filter(dto -> list2.contains(dto.getOrganId())).forEach(dto -> dto.setBillState(1));
list.forEach(accountCheckingSummaryByDayMapper::insert);
list.forEach(dto -> dto.setBillState(1));
list.forEach(dto -> dto.setBillState(dto.getBillState-1));
Person maxAgePerson = personList.stream().max(Comparator.comparing(Person::getAge)).get();
List<BusinessChannel> list =getList();
Map<String, List<BusinessChannel>> group = list.stream().collect(Collectors.groupingBy(BusinessChannel::getMchId));
Map<Integer, Integer> projectOrerMap = fundInvestProjectOrders.stream().collect(Collectors.toMap(FundInvestProjectOrder::getProjectId, FundInvestProjectOrder::getOrder));
Map<Integer, FundInvestProjectOrder> projectOrerMap = fundInvestProjectOrders.stream().collect(Collectors.toMap(FundInvestProjectOrder::getProjectId, i -> i));
Map<String, List<OrganChannelPO>> channelMap =list.stream().collect(groupingBy(o -> o.getMchId() + "_" + o.getAppId()));
long count = list.stream().filter(s -> s.getSex().equals("女")).count();
List<Long> idList = AList.stream.map(A::getId).collect(Collectors.toList());
List<Long> idList = AList.stream.map(A::getId).distinct().collect(Collectors.toList());
AlipayNotifyImage实体类,transactionId、imageId实体对象中的两个字段。以两个字段一起去重
List<AlipayNotifyImage> distinctClass = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.getTransactionId() + ";" + o.getImageId()))), ArrayList::new));
以一个字段去重
list = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.getImageId()))), ArrayList::new));
spaceCodeList是一个List<String>
Map<String, Long> collect = spaceCodeList.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
List<String> result = collect.entrySet().stream()
.filter(e -> e.getValue() > 1).map(Map.Entry::getKey)
.collect(Collectors.toList());
Function.identity()代表元素自身
List<CheckVO> voList = list.stream().map(po -> {
CheckVO vo=new CheckVO();
BeanUtils.copyProperties(po,vo);
return vo;
}).collect(Collectors.toList());
根据指定元素反排序
List<BillSummaryExcel> resultDetailExcelList = detailExcelList.stream().sorted(Comparator.comparing(BillSummaryExcel::getBillDate).reversed()).collect(Collectors.toList());
myMap.forEach((k,v) -> {
System.out.println(k + ":" + v);
});