stream流在项目中常见操作

package org.hzero.demo.java300.JavaStream18;

import com.alibaba.fastjson.JSONArray;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.hzero.demo.TestLeetCode.Son;

import java.util.*;
import java.util.stream.Collectors;

public class TestStream {
   /**
    * 总结一个流式处理可以分为三个部分:转换成流、中间操作、终端操作。
    * 集合.stream变成流  数组流  文件流
    * 中间操作 filter过滤 distinct去重 limit限制  sorted排序 map映射 flatmap
    * 终端操作
    * anymatch allmatch查找 collect收集
    * groupingBy 归类 reduce规约
    * findFrist查找第一个
    * 详解链接
    * https://www.cnblogs.com/gaopengfirst/p/10813803.html
    *
    * @param args
    */

   public static void main(String[] args) {

      String sssss = "wangqianyu-1110";
      System.out.println(StringUtils.substringAfter(sssss , "-"));
      //初始化集合
      List<User> list = new ArrayList<User>() {
         {
            add(new User(1L, "张三", 10, "清华大学"));
            add(new User(2L, "李四", 12, "清华大学"));
            add(new User(3L, "王五", 15, "清华大学"));
            add(new User(4L, "赵六", 12, "清华大学"));
            add(new User(5L, "田七", 25, "北京大学"));
            add(new User(6L, "小明", 16, "北京大学"));
            add(new User(7L, "小红", 14, "北京大学"));
            add(new User(8L, "小华", 14, "浙江大学"));
            add(new User(9L, "小丽", 17, "浙江大学"));
            add(new User(10L, "小何", 10, "浙江大学"));
         }
      };

      //測試过滤方法
      fileter(list);

      //distinct去重
      distinct(list);

      //取前两名
      limit(list, 2);

      //排序
      sorted(list);

      //skip跳过
      skip(list, 3);

      //映射
      map(list);

      //求和
      mapToInt(list);

      //扁平化流
      flatMap();

      //查找
      allMatch(list);

      //查找第一个
      findFirst(list);

      //规约
      reduce(list);

      //计数
      counting(list);

      //计算最大值
      maxBy(list);

      //通过收集取总和
      summingInt(list);

      //拼接
      joining(list);

      //根据某个字段去重
      distinctBySchool(list);

   }

   /**
    * 1. 过滤
    * 1.1 filter
    * 我们希望过滤筛选出处所有学校是清华大学的user:
    */
   public static void fileter(List<User> list) {
      list = list.stream().filter(user -> user.getSchool().equals("清华大学")).collect(Collectors.toList());
      if (CollectionUtils.isNotEmpty(list)) {
         list.forEach(user -> System.out.print(user.getName() + ","));
      }
      System.out.println("fileter==================");
   }

   /**
    * 1.2 distinct
    * 去重,我们希望获取大学代表
    * //过滤出有效的卡信息(根据患者id去重)
    *  List effectList = patientServerVOList.stream().
    *  collect(Collectors.collectingAndThen(Collectors.toCollection(()->
    *  new TreeSet<>(Comparator.comparing(PatientServerVO::getPatId))),ArrayList::new));
    */
   public static void distinctBySchool(List<User> list) {
      list = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(
            () -> new TreeSet<>(Comparator.comparing(User::getSchool))) , ArrayList :: new)
      );
      System.out.println("distinctBySchool==================");
      System.out.println(list.size());
      List<Integer> ageList = list.stream().map(user -> user.getAge()).distinct().collect(Collectors.toList());
      if (CollectionUtils.isNotEmpty(list)) {
         ageList.forEach(integer -> System.out.print(integer + ","));
      }
   }

   /**
    * 1.2 distinct
    * 去重,我们希望获取所有user的年龄(年龄不重复)
    */
   public static void distinct(List<User> list) {
      List<Integer> ageList = list.stream().map(user -> user.getAge()).distinct().collect(Collectors.toList());
      if (CollectionUtils.isNotEmpty(list)) {
         ageList.forEach(integer -> System.out.print(integer + ","));
      }
      System.out.println("distinct==================");
   }

   /**
    * 1.3 limit
    * 返回前n个元素的流,当集合的长度小于n时,则返回所有集合。
    * 如获取年龄是偶数的前2名user:
    */
   public static void limit(List<User> list, int n) {
      list = list.stream().filter(user -> user.getAge() % 2 == 0).limit(n).collect(Collectors.toList());
      if (CollectionUtils.isNotEmpty(list)) {
         list.forEach(user -> System.out.print(user.getName() + ","));
      }
      System.out.println("limit==================");
   }

   /**
    * 1.4 sorted
    * 排序,如现在我想将所有user按照age从大到小排序
    */
   public static void sorted(List<User> list) {
      //Map<String, String> map = list.stream().collect(Collectors.toMap(User :: getName , User -> User.getSchool()== null ? "" : User.getSchool()));
      list = list.stream().sorted((user1, user2) -> user2.getAge() - user1.getAge()).collect(Collectors.toList());
      if (CollectionUtils.isNotEmpty(list)) {
         list.forEach(user -> System.out.print(user.getName() + ","));
      }
      System.out.println("sorted==================");
   }

   /**
    * 1.5 skip
    * 跳过n个元素后再输出
    * 如输出list集合跳过前两个元素后的list
    */
   public static void skip(List<User> list, int n) {
      list = list.stream().skip(n).collect(Collectors.toList());
      if (CollectionUtils.isNotEmpty(list)) {
         list.forEach(user -> System.out.print(user.getName() + ","));
      }
      System.out.println("skip==================");
   }


   /**
    * 2 映射
    * 2.1 map
    * 就是讲user这个几个精简为某个字段的集合
    * 如我现在想知道学校是清华大学的所有学生的姓名:
    */
   public static void map(List<User> list) {
      List<String> nameList = list.stream().
            filter(user ->
                  "清华大学".equals(user.getSchool())).
            map(user ->
                  user.getName().equals("") ? "" : user.getName())
            .collect(Collectors.toList());
      List<String> list1 = list.stream().map(User ->
            StringUtils.isBlank(User.getName())
                  ? "" : User.getName()).collect(Collectors.toList());
      if (CollectionUtils.isNotEmpty(nameList)) {
         nameList.forEach(s -> System.out.print(s + ","));
      }
      System.out.println("map==================");
   }

   /**
    * 除了上面这类基础的map,java8还提供了
    * mapToDouble(ToDoubleFunction<? super T> mapper),
    * mapToInt(ToIntFunction<? super T> mapper),
    * mapToLong(ToLongFunction<? super T> mapper),
    * 这些映射分别返回对应类型的流,
    * java8为这些流设定了一些特殊的操作,比如查询学校是清华大学的user的年龄总和:
    */
   public static void mapToInt(List<User> list) {
      int ageNum = list.stream().
            filter(user ->
                  "清华大学".equals(user.getSchool())).
            mapToInt(User::getAge).sum();
      System.out.println("清华大学所有人加起来年龄:" + ageNum);
      System.out.println("mapToInt==================");
   }

   /**
    * flatMap与map的区别在于 flatMap是将一个流中的每个值都转成一个个流,
    * 然后再将这些流扁平化成为一个流 。举例说明,
    * 假设我们有一个字符串数组String[] strs = {"hello", "world"};,
    * 我们希望输出构成这一数组的所有非重复字符,那么我们用map和flatMap 实现如下:
    */
   public static void flatMap() {
      String[] strings = {"Hello", "World"};
      List l11 = Arrays.stream(strings).map(str -> str.split("")).map(str2 -> Arrays.stream(str2)).distinct().collect(Collectors.toList());
      List l2 = Arrays.asList(strings).stream().map(s -> s.split("")).flatMap(Arrays::stream).distinct().collect(Collectors.toList());
      System.out.println(l11.toString());
      System.out.println(l2.toString());
      System.out.println("flatMap==================");
      /**
       * 由上我们可以看到使用map并不能实现我们现在想要的结果,
       * 而flatMap是可以的。这是因为在执行map操作以后,
       * 我们得到是一个包含多个字符串(构成一个字符串的字符数组)的流,
       * 此时执行distinct操作是基于在这些字符串数组之间的对比,所以达不到我们希望的目的;
       * flatMap将由map映射得到的Stream<String[]>,转换成由各个字符串数组映射成的流Stream<String>,
       * 再将这些小的流扁平化成为一个由所有字符串构成的大流Steam<String>,
       * 从而能够达到我们的目的。
       */
   }


   /**
    * 3.1 allMatch
    * 用于检测是否全部都满足指定的参数行为,如果全部满足则返回true,
    * 例如我们判断是否所有的user年龄都大于9岁,实现如下:
    * anyMatch则是检测是否存在一个或多个满足指定的参数行为,如果满足则返回true
    * noneMatch用于检测是否不存在满足指定行为的元素,如果不存在则返回true
    */
   public static void allMatch(List<User> list) {
      Boolean ageFlag = list.stream().
            allMatch(user ->
                  user.getAge() > 9);
      System.out.println("是否所有的user年龄都大于9岁:" + ageFlag);
      System.out.println("allMatch==================");
   }

   /**
    * 3.4 findFirst
    * findFirst用于返回满足条件的第一个元素,比如返回年龄大于12岁的user中的第一个,实现如下:
    * 相似如
    * findAny相对于findFirst的区别在于,findAny不一定返回第一个,而是返回任意一个,
    * 比如返回年龄大于12岁的user中的任意一个
    */
   public static void findFirst(List<User> list) {
      Optional<User> users = Optional.ofNullable(list)
            .orElse(new ArrayList<>())
            .stream()
            .filter(user ->
                  "清华大学".equals(user.getSchool())).
                  findFirst();
      if (users.isPresent()) {
         System.out.println("清华大学第一人:" + users.get().getName());
      }
      System.out.println("findFirst==================");
   }

   /**
    * 现在我的目标不是返回一个新的集合,而是希望对经过参数化操作后的集合进行进一步的运算,那么我们可用对集合实施归约操作。java8的流式处理提供了reduce方法来达到这一目的。
    * <p>
    * 比如我现在要查出学校是清华大学的所有user的年龄之和:
    */
   public static void reduce(List<User> list) {
      //前面用到的方法
      Integer ages = list.stream().filter(student -> "清华大学".equals(student.getSchool())).mapToInt(User::getAge).sum();
      System.out.println(ages);
      System.out.println("归约 - - 》 start ");
      Integer ages2 = list.stream().filter(student -> "清华大学".equals(student.getSchool())).map(User::getAge).reduce(0, (a, c) -> a + c);
      Integer ages3 = list.stream().filter(student -> "清华大学".equals(student.getSchool())).map(User::getAge).reduce(0, Integer::sum);
      Integer ages4 = list.stream().filter(student -> "清华大学".equals(student.getSchool())).map(User::getAge).reduce(Integer::sum).get();
      System.out.println(ages2);
      System.out.println(ages3);
      System.out.println(ages4);
      System.out.println("归约 - - 》 end ");
   }

   /**
    * 前面利用collect(Collectors.toList())是一个简单的收集操作,
    * 是对处理结果的封装,对应的还有toSet、toMap,以满足我们对于结果组织的需求。
    * 这些方法均来自于java.util.stream.Collectors,我们可以称之为收集器。
    * <p>
    * 收集器也提供了相应的归约操作,但是与reduce在内部实现上是有区别的
    * ,收集器更加适用于可变容器上的归约操作,
    * 这些收集器广义上均基于Collectors.reduc
    */
   public static void counting(List<User> list) {
      long sum = list.stream()
            .filter(user ->
                  user.getSchool().equals("清华大学")).
                  collect(Collectors.counting());
      System.out.println("清华大学有" + sum + "人");
   }

   /**
    * 5.2 maxBy、minBy
    * <p>
    * 计算最大值和最小值
    * 如我现在计算user的年龄最大值和最小值:
    */
   public static void maxBy(List<User> list) {
      Integer num = list.stream().collect(Collectors.
            maxBy((age1, age2) -> age1.getAge() - age2.getAge())).get().getAge();
      System.out.println("年纪最大的是:" + num + "岁");
      System.out.println("=================maxBy");
   }

   /**
    * 取总和
    * summingInt、summingLong、summingDouble
    * 取平均
    * averageInt、averageLong、averageDouble
    * 一次性查询元素个数、总和、最大值、最小值和平均值
    * summarizingInt、summarizingLong、summarizingDouble
    */
   public static void summingInt(List<User> list) {
      int sumAge = list.stream().collect(Collectors.summingInt(User::getAge));
      System.out.println(sumAge);
      int sumAge2 = list.stream().mapToInt(User::getAge).sum();
      System.out.println(sumAge2);
      Long startTime = System.currentTimeMillis();
      IntSummaryStatistics intSummaryStatistics = list.stream().collect(Collectors.summarizingInt(User::getAge));
      System.out.println("耗时" + (System.currentTimeMillis() - startTime));
      System.out.println(intSummaryStatistics);
      System.out.println("============summingInt");
   }


   /**
    * 5.6 joining
    * 字符串拼接
    * 如输出所有user的名字,用“,”隔开
    */
   public static void joining(List<User> list) {
      String names = list.stream().map(User::getName).collect(Collectors.joining(","));
      System.out.println(names);
      System.out.println("============joining");
   }

   /**
    * groupingBy 根据某个属性分组
    */


   /**
    * 替换集合中某个字段为固定的值时,可以这样
    */
   public void testForeach(){
      List<Son> sonList = new ArrayList<>();
      sonList.add(new Son("111" , 1));
      sonList.add(new Son("222" , 2));
      System.out.println(sonList);
      System.out.println(sonList.get(0).getName());
      sonList.stream().forEach(son1 ->
            son1.setName("testStream"));
      System.out.println(sonList.toString());
      System.out.println(sonList.get(0).getName());
   }

   /**
    * 使用java8的流进行转换两个对象属性不同的集合
    * */
   public void test(){
      /**
      List<Student> students =new ArrayList<>();
      students.add(new Student("1","aaa","男",new Date()));
      students.add(new Student("2","bbb","女",new Date()));
      List<User> copyUsers = students.stream().map(s ->
            {
               User user = new User();
               user.setUid(s.getId());
               user.setUname(s.getName());
               return user;
            }
      ).collect(Collectors.toList());
      System.out.println(copyUsers);
       * */
   }






}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值