Java8 Stream常用API整理(值得收藏)

Wesley13
• 阅读 620

点击上方“Java专栏”,选择“置顶或者星标”

第一时间阅读精彩文章!

点击这段文字获取:****5个可以写到简历的项目实战视频教程(含源码)

题 图:pexels

作 者:程铭程铭你快成名

来 源:https://blog.csdn.net/wangchengming1/article/details/89245402

Java8中有两大最为重要的改变,第一个是Lambda表达式,另外一个则是Stream API。

  • 流是 Java8 引入的全新概念,它用来处理集合中的数据。

  • 众所周知,集合操作非常麻烦,若要对集合进行筛选、投影,需要写大量的代码,而流是以声明的形式操作集合,它就像 SQL 语句,我们只需告诉流需要对集合进行什么操作,它就会自动进行操作,并将执行结果交给你,无需我们自己手写代码。

  • 在项目中使用 Stream API 可以大大提高效率以及代码的可读性,使我们对数据进行处理的时候事半功倍。

这篇博文以实战角度出发,讲解平时开发中常用 API 的用法以及一些注意的地方。

首先创建一个对象

public class Employee {  private int id;  private String name;  private int age;  private double salary;  private Status status;  public enum Status {    FREE, BUSY, VOCATION;  }  public Employee() {  }  public Employee(String name) {    this.name = name;  }  public Employee(String name, int age) {    this.name = name;    this.age = age;  }    public Employee(int id, String name, int age, double salary) {    this.id = id;    this.name = name;    this.age = age;    this.salary = salary;  }  public Employee(int id, String name, int age, double salary, Status status) {    this.id = id;    this.name = name;    this.age = age;    this.salary = salary;    this.status = status;  }  //省略get,set等。。。}

随便初始化一些数据

List<Employee> empList = Arrays.asList(new Employee(102, "李四", 59, 6666.66, Status.BUSY),      new Employee(101, "张三", 18, 9999.99, Status.FREE), new Employee(103, "王五", 28, 3333.33, Status.VOCATION),      new Employee(104, "赵六", 8, 7777.77, Status.BUSY), new Employee(104, "赵六", 8, 7777.77, Status.FREE),      new Employee(104, "赵六", 8, 7777.77, Status.FREE), new Employee(105, "田七", 38, 5555.55, Status.BUSY));

中间操作

根据条件筛选 filter

/*** 接收Lambda, 从流中排除某些元素。*/@Testvoid testFilter() {  empList.stream().filter((e) -> {    return e.getSalary() >= 5000;  }).forEach(System.out::println);}

跳过流的前n个元素 skip

/*** 跳过元素,返回一个扔掉了前n个元素的流。*/@Testvoid testSkip() {  empList.stream().filter((e) -> e.getSalary() >= 5000).skip(2).forEach(System.out::println);}

去除重复元素 distinct

/*** 筛选,通过流所生成元素的 hashCode() 和 equals() 去除重复元素*/@Testvoid testDistinct() {  empList.stream().distinct().forEach(System.out::println);}

截取流的前n个元素 limit

/*** 截断流,使其元素不超过给定数量。*/@Testvoid testLimit() {  empList.stream().filter((e) -> {    return e.getSalary() >= 5000;  }).limit(3).forEach(System.out::println);}

映射 map

/*** 接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素*/@Testvoid testMap() {  empList.stream().map(e -> e.getName()).forEach(System.out::println);  empList.stream().map(e -> {    empList.forEach(i -> {      i.setName(i.getName() + "111");    });    return e;  }).collect(Collectors.toList());}

自然排序 sorted

/*** 产生一个新流,其中按自然顺序排序*/@Testvoid testSorted() {  empList.stream().map(Employee::getName).sorted().forEach(System.out::println);}

自定义排序 sorted(Comparator comp)

/*** 产生一个新流,其中按自然顺序排序*/@Testvoid testSortedComparator() {  empList.stream().sorted((x, y) -> {   if (x.getAge() == y.getAge()) {     return x.getName().compareTo(y.getName());    } else {     return Integer.compare(x.getAge(), y.getAge());   }  }).forEach(System.out::println);}
最终操作

是否匹配任一元素 anyMatch

/** * 检查是否至少匹配一个元素 */@Testvoid testAnyMatch() {  boolean b = empList.stream().anyMatch((e) -> e.getStatus().equals(Status.BUSY));  System.out.println("boolean is : " + b);}

是否匹配所有元素 allMatch

/** * 检查是否匹配所有元素 */@Testvoid testAllMatch() {  boolean b = empList.stream().allMatch((e) -> e.getStatus().equals(Status.BUSY));  System.out.println("boolean is : " + b);}

是否未匹配所有元素 noneMatch

/** * 检查是否没有匹配的元素 */@Testvoid testNoneMatch() {  boolean b = empList.stream().noneMatch((e) -> e.getStatus().equals(Status.BUSY));  System.out.println("boolean is : " + b);}

返回第一个元素 findFirst

/** * 返回第一个元素 */@Testvoid testFindFirst() {  Optional<Employee> op = empList.stream().sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()))      .findFirst();  if (op.isPresent()) {    System.out.println("first employee name is : " + op.get().getName().toString());  }}

返回流中任意元素 findAny

/** * 返回当前流中的任意元素 */@Testvoid testFindAny() {  Optional<Employee> op = empList.stream().sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()))      .findAny();  if (op.isPresent()) {    System.out.println("any employee name is : " + op.get().getName().toString());  }}

返回流的总数 count

/** * 返回流中元素的总个数 */@Testvoid testCount() {  long count = empList.stream().filter((e) -> e.getStatus().equals(Status.FREE)).count();  System.out.println("Count is : " + count);}

返回流中的最大值 max

/** * 返回流中最大值 */@Testvoid testMax() {  Optional<Double> op = empList.stream().map(Employee::getSalary).max(Double::compare);  System.out.println(op.get());}

返回流中的最小值 min

/** * 返回流中最小值 */@Testvoid testMin() {  Optional<Employee> op2 = empList.stream().min((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));  System.out.println(op2.get());}

归约 reduce
归约是将集合中的所有元素经过指定运算,折叠成一个元素输出

/** * 可以将流中元素反复结合起来,得到一个值。返回T */@Testvoid testReduce() {  Optional<Double> op = empList.stream().map(Employee::getSalary).reduce(Double::sum);  System.out.println(op.get());}/** * 可以将流中元素反复结合起来,得到一个值,返回Optional< T> */@Testvoid testReduce1() {  Optional<Integer> sum = empList.stream().map(Employee::getName).flatMap(Java8Stream::filterCharacter)      .map((ch) -> {        if (ch.equals('六'))          return 1;        else          return 0;      }).reduce(Integer::sum);  System.out.println(sum.get());}

将元素收集到 list 里 Collectors.toList()

/** * 把流中的元素收集到list里。 */@Testvoid testCollectorsToList() {  List<String> list = empList.stream().map(Employee::getName).collect(Collectors.toList());  list.forEach(System.out::println);}

将元素收集到 set 里 Collectors.toSet()

/** * 把流中的元素收集到set里。 */@Testvoid testCollectorsToSet() {  Set<String> list = empList.stream().map(Employee::getName).collect(Collectors.toSet());  list.forEach(System.out::println);}

把流中的元素收集到新创建的集合里 Collectors.toCollection(HashSet::new)

/** * 把流中的元素收集到新创建的集合里。 */@Testvoid testCollectorsToCollection() {  HashSet<String> hs = empList.stream().map(Employee::getName).collect(Collectors.toCollection(HashSet::new));  hs.forEach(System.out::println);}

根据比较器选择最大值 Collectors.maxBy()

/** * 根据比较器选择最大值。 */@Testvoid testCollectorsMaxBy() {  Optional<Double> max = empList.stream().map(Employee::getSalary).collect(Collectors.maxBy(Double::compare));  System.out.println(max.get());}

根据比较器选择最小值 Collectors.minBy()

/** * 根据比较器选择最小值。 */@Testvoid testCollectorsMinBy() {  Optional<Double> max = empList.stream().map(Employee::getSalary).collect(Collectors.minBy(Double::compare));  System.out.println(max.get());}

对流中元素的某个字段求和 Collectors.summingDouble()

/** * 对流中元素的整数属性求和。 */@Testvoid testCollectorsSummingDouble() {  Double sum = empList.stream().collect(Collectors.summingDouble(Employee::getSalary));  System.out.println(sum);}

对流中元素的某个字段求平均值 Collectors.averagingDouble()

/** * 计算流中元素Integer属性的平均值。 */@Testvoid testCollectorsAveragingDouble() {  Double avg = empList.stream().collect(Collectors.averagingDouble(Employee::getSalary));  System.out.println(avg);}

分组,类似sql的 group by Collectors.groupingBy

/** * 分组 */@Testvoid testCollectorsGroupingBy() {  Map<Status, List<Employee>> map = empList.stream().collect(Collectors.groupingBy(Employee::getStatus));  System.out.println(map);}

多级分组

/** * 多级分组 */@Testvoid testCollectorsGroupingBy1() {  Map<Status, Map<String, List<Employee>>> map = empList.stream()      .collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy((e) -> {        if (e.getAge() >= 60)          return "老年";        else if (e.getAge() >= 35)          return "中年";        else          return "成年";      })));  System.out.println(map);}

字符串拼接 Collectors.joining()

/** * 字符串拼接 */@Testvoid testCollectorsJoining() {  String str = empList.stream().map(Employee::getName).collect(Collectors.joining(",", "----", "----"));  System.out.println(str);}



public static Stream<Character> filterCharacter(String str) {  List<Character> list = new ArrayList<>();  for (Character ch : str.toCharArray()) {    list.add(ch);  }  return list.stream();}





  
     
     
     
   
      
      
      
    
       
       
       
     
        
        
        
      
         
         
         
       
          
          
           
           以上,便是今天的分享,希望大家喜欢,觉得内容不错的,欢迎点击「在看」支持,谢谢各位 
                    
            
            
            
          
             
             
             
           
              
              
              
            
               
               
               
             
                
                
                
              
                 
                 
                  
                   
                 
             
                
                
                
            
               
               
               
           
              
              
              
          
             
             
             
         
            
            
             
          
      
         
         
         
     
        
        
        
    
       
       
       
   
      
      
      
  
     
     
     

   
   
   
 
    
    
    150页,8W字的Java知识手册

   
   
   获取方式:1、公众号后台回复「手册」2、扫描下方二维码,回复「手册」 
    
    
    
  
     
     
     👆
  
     
     
     长按上方二维码 2 秒
 
    
    
    
 
    
    
    
  
     
     
     回复「
  
     
     
     手册
  
     
     
     」即可获取资料
 
    
    
    

本文分享自微信公众号 - Java专栏(finishbug)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Stella981 Stella981
3年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Wesley13 Wesley13
3年前
IM消息系统的设计和实现
点击关注上方“JAVA开发大本营”,设为“置顶或星标”,第一时间送达技术干货。!(https://oscimg.oschina.net/oscnet/6cc35fe4f21c47a2b27b53fbdd52d064.png)全文预计阅读6分钟!(https://osci
Stella981 Stella981
3年前
Docker 部署SpringBoot项目不香吗?
  公众号改版后文章乱序推荐,希望你可以点击上方“Java进阶架构师”,点击右上角,将我们设为★“星标”!这样才不会错过每日进阶架构文章呀。  !(http://dingyue.ws.126.net/2020/0920/b00fbfc7j00qgy5xy002kd200qo00hsg00it00cj.jpg)  2
Stella981 Stella981
3年前
200的大额人民币即将面世?央行:Yes!
点击上方蓝字关注我们!(https://oscimg.oschina.net/oscnet/2a1c2ac00bf54458a78c48a6c2e547d5.png)点击上方“印象python”,选择“星标”公众号重磅干货,第一时间送达!!(
Wesley13 Wesley13
3年前
Java面试题阶段汇总
点击上方“Java知音”,选择“置顶公众号”技术文章第一时间送达!知音专栏 Javaweb练手项目源码(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzI4Njc5NjM1NQ%3D%3D%26mid
可莉 可莉
3年前
200的大额人民币即将面世?央行:Yes!
点击上方蓝字关注我们!(https://oscimg.oschina.net/oscnet/2a1c2ac00bf54458a78c48a6c2e547d5.png)点击上方“印象python”,选择“星标”公众号重磅干货,第一时间送达!!(
Stella981 Stella981
3年前
Rabbitmq 延迟队列实现定时任务,实战
点击上方“Java专栏”,选择“置顶或者星标”第一时间阅读精彩文章!1、☞程序员进阶必备资源免费送「21种技术方向!」点击查看☜(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU5
Wesley13 Wesley13
3年前
Java面试定会遇到的56个面试题
点击关注上方“java大数据修炼之道”,设为“置顶或星标”,你想要的技术干货第一时间送达。精品专栏java日志性能哪些事 ★★★★(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU1Njcz