java jdk-Stream操作

时间:2025-08-31 08:24:02来源:互联网

下面小编就为大家分享一篇java jdk-Stream操作,具有很好的参考价值,希望对大家有所帮助。

Stream操作

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 后,就要开始对里面的元素进行各类操作了。常见的操作可以归类如下。

 

  • Intermediate中间操作
    • map:通过一个 Function 把一个元素类型为 T 的流转换成元素类型为 R 的流。
    • flatMap:通过一个 Function 把一个元素类型为 T 的流中的每个元素转换成一个元素类型为 R 的流,再把这些转换之后的流合并。
    • filter:过滤流中的元素,只保留满足由 Predicate 所指定的条件的元素。
    • distinct:使用 equals 方法来删除流中的重复元素。
    • limit:截断流使其最多只包含指定数量的元素。
    • skip:返回一个新的流,并跳过原始流中的前 N 个元素。
    • sorted:对流进行排序。
    • peek:返回的流与原始流相同。当原始流中的元素被消费时,会首先调用 peek 方法中指定的 Consumer 实现对元素进行处理。
    • dropWhile:从原始流起始位置开始删除满足指定 Predicate 的元素,直到遇到第一个不满足 Predicate 的元素。
    • takeWhile:从原始流起始位置开始保留满足指定 Predicate 的元素,直到遇到第一个不满足 Predicate 的元素。
  • Terminal终结操作:产生最终的结果
    • forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 iterator
    • .forEach 和 forEachOrdered 对流中的每个元素执行由 Consumer 给定的实现。在使用 forEach 时,并没有确定的处理元素的顺序;forEachOrdered 则按照流的相遇顺序来处理元素,如果流有确定的相遇顺序的话。
    • reduce进行递归计算
    • collect生成新的数据结构
  • Short-circuiting
    • anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 limit

 

map

它的作用就是把 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());

flatMap

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

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());

 

filter筛选并修改

list.stream().filter(dto -> list2.contains(dto.getOrganId())).forEach(dto -> dto.setBillState(1));

 

其他总结

forEach配合流

list.forEach(accountCheckingSummaryByDayMapper::insert);
list.forEach(dto -> dto.setBillState(1));
list.forEach(dto -> dto.setBillState(dto.getBillState-1));

 

获取年龄最大的Person

Person maxAgePerson = personList.stream().max(Comparator.comparing(Person::getAge)).get();

list进行group变map

List<BusinessChannel> list =getList();
Map<String, List<BusinessChannel>> group = list.stream().collect(Collectors.groupingBy(BusinessChannel::getMchId));

list进行Collectors.toMap转为map

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));

 

list对多个字段组合进行group

Map<String, List<OrganChannelPO>> channelMap =list.stream().collect(groupingBy(o -> o.getMchId() + "_" + o.getAppId()));

 

获取符合条件在集合中的数量

long count = list.stream().filter(s -> s.getSex().equals("女")).count();

获取集合中的元素id的集合

List<Long> idList = AList.stream.map(A::getId).collect(Collectors.toList());

 

获取id集合并去重

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转换

    List<CheckVO> voList = list.stream().map(po -> {
            CheckVO vo=new CheckVO();
            BeanUtils.copyProperties(po,vo);
            return vo;
        }).collect(Collectors.toList());

list元素排序

根据指定元素反排序

List<BillSummaryExcel> resultDetailExcelList = detailExcelList.stream().sorted(Comparator.comparing(BillSummaryExcel::getBillDate).reversed()).collect(Collectors.toList());

 

map的foreach遍历

myMap.forEach((k,v) -> {
    System.out.println(k + ":" + v);
 });

 

本站部分内容转载自互联网,如果有网站内容侵犯了您的权益,可直接联系我们删除,感谢支持!