Stream流的一些使用方法

打印 上一主题 下一主题

主题 897|帖子 897|积分 2691

一、创建Stream数据流


  • Stream流创建
    1. Stream<Integer> stream = Stream.of(0, 1, 2, 3, 4, 5);
    复制代码
  • Collection创建
    1. List<Integer> integerList = new ArrayList<>();
    2. integerList.add(0);
    3. integerList.add(1);
    4. integerList.add(2);
    5. integerList.add(3);
    6. integerList.add(4);
    7. integerList.add(5);
    8. Stream<Integer> listStream = integerList.stream();
    复制代码
  • Arrays创建
    1. int[] intArr = {0, 1, 2, 3, 4, 5};
    2. IntStream arrayStream = Arrays.stream(intArr);
    复制代码
  • 文件创建
    1. try {
    2.      Stream<String> fileStream = Files.lines(Paths.get("data.txt"), Charset.defaultCharset());
    3. } catch (IOException e) {
    4.      e.printStackTrace();
    5. }
    复制代码
  • 函数创建(无限流)

    Stream.iterator() 方法接受两个参数,第一个为初始化值,第二个为进行的函数操纵,因为 iterator 生成的流为无限流,通过 limit 方法对流进行了截断
    1. Stream<Integer> iterateStream = Stream.iterate(0, n -> n + 2).limit(5);
    复制代码
    Stream.generate() 方法接受一个参数,方法参数类型为 Supplier ,由它为流提供值。generate 生成的流也是无限流,因此通过 limit 对流进行了截断
    1. Stream<Double> generateStream = Stream.generate(Math::random).limit(5);
    复制代码
二、Stream流中间操纵


  • filter过滤
    1. // filter:输出ID大于6的user对象
    2. List<User> filetrUserList = userList.stream().filter(user -> user.getId() > 6).collect(Collectors.toList());
    3. filetrUserList.forEach(System.out::println);
    4. //查找列表中以B开头的第一个字符串
    5. String result2=names.stream().filter(name->name.startsWith("B")).findFirst().orElse("未找到");
    复制代码
  • map映射

    map 元素映射,提供一个映射规则,将流中的每一个元素替换成指定的元素
    1. // map
    2. List<String> mapUserList = userList.stream().map(user -> user.getName() + "用户").collect(Collectors.toList());
    3. mapUserList.forEach(System.out::println);
    复制代码
  • distinct去重

    distinct 去重,去除流中的重复的数据,这个方法是没有参数的,去重的规则与 hashSet 雷同
    1. // 去重
    2. dataSource.distinct().forEach(System.out::println);
    复制代码
  • sorted排序

    sorted 排序,将流中的数据,按照其对应的类实现的 Comparable 接口提供的比较规则进行排序
    1. // sorted:排序,根据名字倒序
    2. userList.stream().sorted(Comparator.comparing(User::getName).reversed()).collect(Collectors.toList()).forEach(System.out::println);
    3. //将集合中所有元素排序并大写输出
    4. List<String> words= Arrays.asList("banana","apple","orange");
    5. words.stream().sorted().map(String::toUpperCase).forEach(System.out::println);
    复制代码
  • limit & skip 限制 & 跳过


    • limit 限制,表示截取流中的指定数量的数据(从第0开始),丢弃剩余部分
    • skip 跳过,表示跳过指定数量的数据,截取剩余部分
    1. // 获取成绩的[3,5]名
    2. dataSource.sorted((s1,s2) -> s2.score - s1.score).distinct()
    3.             .limit(5)
    4.             .skip(2)
    5.             .forEach(System.out::println);
    复制代码
  • flatMap扁平化映射

    使用 flatMap 方法的效果是,各个数组并不是分别映射成一个流,而是映射成流的内容。所有使用 map(Arrays::stream) 时生成的单个流都被归并起来,即扁平化为一个流
    1. // 一般是用在map映射完成后,流中的数据是一个容器,而我们需要再对容器中的数据进行处理,此时使用扁平化映射
    2. // 将字符串数组中的数据读取到流中
    3. Stream<String> stream = Arrays.stream(s);  
    4. // 统计字符串数组中所有出现的字符
    5. stream.map(e -> e.split(""))
    6.             .flatMap(Arrays::stream)
    7.             .distinct()
    8.             .forEach(System.out::print);
    复制代码
  • peek对元素进行遍历处理
    1. // peek:对元素进行遍历处理,每个用户ID加1输出
    2. userList.stream().peek(user -> user.setId(user.getId()+1)).forEach(System.out::println);
    复制代码
三、Stream流终端操纵

Stream 流执行完终端操纵之后,无法再执行其他动作,否则会报状态异常,提示该流已经被执行操纵或者被关闭,想要再次执行操纵必须重新创建 Stream 流
一个流有且只能有一个终端操纵,当这个操纵执行后,流就被关闭了,无法再被操纵,因此一个流只能被遍历一次,若想在遍历须要通过源数据在生成流。
终端操纵的执行,才会真正开始流的遍历。如 count、collect 等

  • collect收集器

    collect 将流中的数据整合起来
    1. // collect:收集器,将流转换为其他形式
    2. Set set = userList.stream().collect(Collectors.toSet());
    3. set.forEach(System.out::println);
    4. System.out.println("--------------------------");
    5. List list = userList.stream().collect(Collectors.toList());
    6. list.forEach(System.out::println);
    复制代码
  • forEach 遍历流

    forEach 遍历流中数据
    1. // forEach:遍历流
    2. userList.stream().forEach(user -> System.out.println(user));
    3. userList.stream().filter(user -> "上海".equals(user.getCity())).forEach(System.out::println);
    复制代码
  • findFirst & findAny 获取流中的元素

    findFirst 获取流中的一个元素,获取的是流中的首元素,在进行元素获取的时间,无论是串行流还是并行流,获取的都是首元素
    1. // findFirst:返回第一个元素
    2. User firstUser = userList.stream().findFirst().get();
    3. User firstUser1 = userList.stream().filter(user -> "上海".equals(user.getCity())).findFirst().get();
    复制代码
    findAny 获取流中的一个元素,通常是首元素,但在并行流中,获取的可能不是首元素。在进行元素获取的时间,串行流一定获取到的是流中的首元素,并行流获取到的可能是首元素,也可能不是
    1. // findAny:将返回当前流中的任意元素
    2. User findUser = userList.stream().findAny().get();
    3. User findUser1 = userList.stream().filter(user -> "上海".equals(user.getCity())).findAny().get();
    复制代码
  • count总数

    count 返回流中元素总数
    1. // count:返回流中元素总数
    2. long count = userList.stream().filter(user -> user.getAge() > 20).count();
    3. System.out.println(count);
    复制代码
  • sum求和
    1. // sum:求和
    2. int sum = userList.stream().mapToInt(User::getId).sum();
    3. //对集合元素求和
    4. List<Integer> numbers= Arrays.asList(3,7,2,8,10,1,5,6);
    5. //第一种方法
    6. Integer r1=numbers.stream().mapToInt(Integer::intValue).sum();
    7. //第二种方法
    8. Integer reduce = numbers.stream().reduce(0, Integer::sum);
    复制代码
  • max & min 最大 & 最小
    1. // max:最大值
    2. int max = userList.stream().max(Comparator.comparingInt(User::getId)).get().getId();
    3. // min:最小值
    4. int min = userList.stream().min(Comparator.comparingInt(User::getId)).get().getId();
    复制代码
  • reduce 聚合

    reduce 将流中的数据按照一定的规则聚合起来
    1. // reduce:将流中元素反复结合起来,得到一个值
    2. Optional reduce = userList.stream().reduce((user, user2) -> {
    3.       return user+user2;
    4. });
    5. if(reduce.isPresent()) System.out.println(reduce.get());
    复制代码
  • allMatch & anyMatch & noneMatch

    allMatch: 只有当流中所有的元素都匹配指定的规则,才会返回 true
    anyMatch: 只要流中的任意数据满足指定的规则,就会返回 true
    noneMatch: 只有当流中所有的元素都不满足指定的规则,才会返回 true
    1. // allMatch:检查是否匹配所有元素
    2. boolean matchAll = userList.stream().allMatch(user -> "北京".equals(user.getCity()));
    3. // anyMatch:检查是否至少匹配一个元素
    4. boolean matchAny = userList.stream().anyMatch(user -> "北京".equals(user.getCity()));
    5. // noneMatch:检查是否没有匹配所有元素,返回 boolean
    6. boolean nonaMatch = userList.stream().allMatch(user -> "北京".equals(user.getCity()));
    复制代码
四、Collect收集

Collector:效果收集策略的核心接口,具备将指定元素累加存放到效果容器中的能力;并在Collectors工具中提供了Collector接口的实现类

  • toList

    将用户 ID 存放到 List 聚集中
    1. List<Integer> idList = userList.stream().map(User::getId).collect(Collectors.toList()) ;
    复制代码
  • toMap

    将用户 ID 和 Name 以 Key-Value 形式存放到 Map 聚集中
    1. Map<Integer,String> userMap = userList.stream().collect(Collectors.toMap(User::getId,User::getName));
    复制代码
  • toSet

    将用户所在城市存放到 Set 聚集中
    1. Set<String> citySet = userList.stream().map(User::getCity).collect(Collectors.toSet());
    复制代码
  • counting

    符合条件的用户总数
    1. long count = userList.stream().filter(user -> user.getId()>1).collect(Collectors.counting());
    复制代码
  • sumingInt

    对效果元素即用户 ID 求和
    1. Integer sumInt = userList.stream().filter(user -> user.getId()>2).collect(Collectors.summingInt(User::getId)) ;
    复制代码
    对聚集元素求和
    1. List<Integer> numbers= Arrays.asList(3,7,2,8,10,1,5,6);
    2. Integer r=numbers.stream().collect(Collectors.summingInt(Integer::intValue));
    复制代码
  • minBy

    筛选元素中 ID 最小的用户
    1. User maxId = userList.stream().collect(Collectors.minBy(Comparator.comparingInt(User::getId))).get() ;
    复制代码
  • joining

    将用户所在城市,以指定分隔符链接成字符串
    1. String joinCity = userList.stream().map(User::getCity).collect(Collectors.joining("||"));
    复制代码
  • groupingBy

    按条件分组,以城市对用户进行分组;
    1. Map<String,List<User>> groupCity = userList.stream().collect(Collectors.groupingBy(User::getCity));
    复制代码

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

王海鱼

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表