java8学习整理

由于项目中使用java8中的lambda表达式,因此想学习一下java8中的lambda表达式和stream流。

Lambda表达式的格式:

(匿名内部类被重写方法的形参列表)->{被重写方法的方法体代码}

例如:

public class LambdaDemo1 {
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("线程任务执行!");
            }
        }).start();
}
}

将其进行简化:

public class LambdaDemo1{
    public static void main(String[] args){
     Thread t = new Thread(()->System.out.println("线程任务执行!")).start();
    }
  }

Lambda表达式使用前提:

1)Lambda表达式并不能简化所有匿名内部类的写法
2)Lambda表达式只能简化接口中只有一个抽象方法的匿名内部类形式

Lambda表达式只能简化函数式表达式接口(通常我们可以看到器有@functionalInterface注解)的匿名内部类写法,也即首先必须是接口,接着接口只能有一个抽象方法,此时可以考虑简化。

Lambda表达式简化Comparator接口匿名内部类写法:进行数据排序,采用Comparator

public class LambdaDemo1 {
    public static void main(String[] args) {
        List<Student> lists = new ArrayList<>();
        Student s1 = new Student("小花",16,"女");
        Student s2 = new Student("小红",18,"女");
        Student s3 = new Student("小乐",20,"男");
        collections.addAlls(lists,s1,s2,s3);
        
        //按年龄排序
        collections.sort(lists,new Comparator<student>(){
            @Override
            public int compare(Student s1,Student s2){
                return s1.getAge()-s2.getAge();
            }
        });
        
        System.out.println("===排序后的集合==="+lists);
        
        private String name;
        private int age;
        private String sex;
        //省略get/set
        
    }
}

对上面的进行改写,将匿名方法的形参列表列出来,同时将将箭头指向被重写的方法:

public class LambdaDemo1 {
    public static void main(String[] args) {
        List<Student> lists = new ArrayList<>();
        Student s1 = new Student("小花",16,"女");
        Student s2 = new Student("小红",18,"女");
        Student s3 = new Student("小乐",20,"男");
        collections.addAlls(lists,s1,s2,s3);
        
        //按年龄排序
        collections.sort(lists, (Student s1,Student s2)->{
                return s1.getAge()-s2.getAge();
        });
        
        System.out.println("===排序后的集合==="+lists);
        
        private String name;
        private int age;
        private String sex;
        //省略get/set
        
    }
}

按理说,改写上面这样就可以了,但Lambda表达式的省略写法在此基础上进行了进一步简化:

1)如果lambda表达式的方法体代码只有一行代码,可以省略大括号不写,同时要省略分号
2)如果lambda表达式的方法体代码只有一行代码,可以省略大括号不写,此时如果这行代码是return语句,必须省略return不写,同时必须省略“;”不写
3)参数类型可以省略不写
4)如果只有一个参数,参数类型可以省略,同时()也可以省略

也就是说上面的代码只有一行,我们可以进一步改写,首先去掉大括号,去掉分号,看到说明(2),我们需要去掉return,同时分号去掉,再接着省略参数类型:

public class LambdaDemo1 {
    public static void main(String[] args) {
        List<Student> lists = new ArrayList<>();
        Student s1 = new Student("小花",16,"女");
        Student s2 = new Student("小红",18,"女");
        Student s3 = new Student("小乐",20,"男");
        collections.addAlls(lists,s1,s2,s3);
        
        //按年龄排序
        //return collections.sort(lists, (Student s1,Student s2)->s1.getAge()-s2.getAge());
        //collections.sort(lists, (Student s1,Student s2)->s1.getAge()-s2.getAge());
        //从而可以将其简化
        collections.sort(lists, (s1,s2)->s1.getAge()-s2.getAge());
        
        System.out.println("===排序后的集合==="+lists);
        
        private String name;
        private int age;
        private String sex;
        //省略get/set
        
    }
}

对forEach的简化:

public static void main(String[] args){
 List<String> names = new ArrayList<>();
 names.add("ab");
 names.add("bc");
 names.add("xiao");
 
 nams.forEach(new Comsumer<String>(){
    @Override
    public void accpet(String s){
      System.out.println(s);
    }
 });
}

进行改写:

public static void main(String[] args){
 List<String> names = new ArrayList<>();
 names.add("ab");
 names.add("bc");
 names.add("xiao");
 
 //首先对其进行形参进行提取,再进行方法指向
 //nams.forEach((String s)->{
   //   System.out.println(s);
 //});
 
 //接着进行大括号去掉,分号去掉,去掉类型
//nams.forEach((String s)->System.out.println(s));
////nams.forEach((s)->System.out.println(s));
    
 //接着进行进一步改写,从改写第4条,我们知道参数只有一个时,可以不写,也是最简方案
  nams.forEach(System.out::println);  
}

Stream流的一些学习

筛选操作:

public static void main(String[] args){
  //需求:从集合中筛选出现所有长度为3,且姓张的同志,同时对同名同姓的进行虑重
  List<String> list = new ArrayList<>();
  list.add("张三");
  list.add("张随和");
  list.add("张随和");  
  list.add("张思通");
  list.add("刘倩");
  list.add("冠宏");
  //首先筛选长度为3,接着筛选张姓的,接着进行获取  
  list.stream().filter(s->s.length==3)
      .filter(s->s.startWith("张")).distinct().forEach(System.out::println);  
}

Stream流中筛选操作

从菜肴menu中获取菜肴dish的名称dishName

List<String> list = dish.stream().map(Dish::getName).collect(toList());

从菜肴中获取菜肴的名称,同时对大于300g的进行筛选

List<String> list = dish.stream().map(Dish::getName).filter(s->s.weight>300).collect(toList());

从菜肴中获取菜肴的名称,同时对大于300g的进行筛选,同时根据菜的类型进行分组

Map<Dish.type,List<Dish>> mapList = dish.stream().map(Dish::getName)
.filter(s->s.weight>300).collect(groupingBy(Dish::type));

本文分享自微信公众号 - 后端技术学习(gh_9f5627e6cc61),作者:路行的亚洲

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-05-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • rocketmq学习2

    从启动类中,我们看到:首先创建NamesrvConfig、nettyServerConfig,设置监听端口,将8888改成9876。填充NamesrvConfi...

    路行的亚洲
  • Netty实现简单RPC调用

    我们知道Dubbo是一个RPC框架,那RPC框架需要实现什么?需要实现的是调用远程服务和本地服务一样方便,同时提高调用远程服务的性能。而服务端和客户端之间的关系...

    路行的亚洲
  • java8学习整理二

    java8不但可以提高代码的运行的性能,而且实现起来很优雅,因此学习它是不错的选择。

    路行的亚洲
  • Spring Data REST不完全指南(二)

    上一篇文章介绍了Spring Data REST的功能及特征,以及演示了如何在项目中引入Spring Data REST并简单地启动演示了Spring Data...

    东溪陈姓少年
  • Eureka Server过源码

    Eureka Server启动 入口EurekaServerInitializerConfiguration @Configuration class Eur...

    叔叔
  • 天哪!手动编写mybatis雏形竟然这么简单

    mybaits 在ORM 框架中,可算是半壁江山了,由于它是轻量级,半自动加载,灵活性和易拓展性。深受广大公司的喜爱,所以我们程序开发也离不开mybatis 。...

    程序员爱酸奶
  • Java第三方支付接入案例(支付宝)

    到蚂蚁金服注册开发者账号,注册地址:https://open.alipay.com,用你的 支付宝 账号扫码登录,完善个人信息,选择服务类型。

    朝雨忆轻尘
  • 大话卷积神经网络CNN(干货满满)

    本文创作的主要目的,是对时下最火最流行的深度学习算法的基础知识做一个简介,本人看过许多教程,感觉对小白不是特别友好,尤其是在踩过好多坑之后,于是便有了写这篇文章...

    我是管小亮
  • 徐妈教你使用 JPA 实现乐观锁

    乐观锁的概念就不再赘述了,不了解的朋友请自行百度谷歌之,今天主要说的是在项目中如何使用乐观锁,做成一个小demo。

    芋道源码
  • 花样使用Handler与源码分析

    前几天在跟公司大佬讨论一个问题时,看到他使用Handler的一种方式,旁边的同事在说:以前不是这么用的啊。这个问题引发了我的好奇,虽然当时翻清楚道理了,但是还是...

    砸漏

扫码关注云+社区

领取腾讯云代金券