由于项目中使用java8中的lambda表达式,因此想学习一下java8中的lambda表达式和stream流。
Lambda表达式的格式:
(匿名内部类被重写方法的形参列表)->{被重写方法的方法体代码}
例如:
publicclassLambdaDemo1 { publicstaticvoidmain(String[] args) { newThread(newRunnable() { publicvoidrun() { System.out.println("线程任务执行!"); } }).start(); } }
将其进行简化:
publicclassLambdaDemo1{ publicstaticvoidmain(String[] args){ Threadt=newThread(()->System.out.println("线程任务执行!")).start(); } }
Lambda表达式使用前提:
1)Lambda表达式并不能简化所有匿名内部类的写法2)Lambda表达式只能简化接口中只有一个抽象方法的匿名内部类形式
Lambda表达式只能简化函数式表达式接口(通常我们可以看到器有@functionalInterface注解)的匿名内部类写法,也即首先必须是接口,接着接口只能有一个抽象方法,此时可以考虑简化。
Lambda表达式简化Comparator接口匿名内部类写法:进行数据排序,采用Comparator
publicclassLambdaDemo1 { publicstaticvoidmain(String[] args) { List<Student>lists=newArrayList<>(); Students1=newStudent("小花",16,"女"); Students2=newStudent("小红",18,"女"); Students3=newStudent("小乐",20,"男"); collections.addAlls(lists,s1,s2,s3); //按年龄排序collections.sort(lists,newComparator<student>(){ publicintcompare(Students1,Students2){ returns1.getAge()-s2.getAge(); } }); System.out.println("===排序后的集合==="+lists); privateStringname; privateintage; privateStringsex; //省略get/set } }
对上面的进行改写,将匿名方法的形参列表列出来,同时将将箭头指向被重写的方法:
publicclassLambdaDemo1 { publicstaticvoidmain(String[] args) { List<Student>lists=newArrayList<>(); Students1=newStudent("小花",16,"女"); Students2=newStudent("小红",18,"女"); Students3=newStudent("小乐",20,"男"); collections.addAlls(lists,s1,s2,s3); //按年龄排序collections.sort(lists, (Students1,Students2)->{ returns1.getAge()-s2.getAge(); }); System.out.println("===排序后的集合==="+lists); privateStringname; privateintage; privateStringsex; //省略get/set } }
按理说,改写上面这样就可以了,但Lambda表达式的省略写法在此基础上进行了进一步简化:
1)如果lambda表达式的方法体代码只有一行代码,可以省略大括号不写,同时要省略分号2)如果lambda表达式的方法体代码只有一行代码,可以省略大括号不写,此时如果这行代码是return语句,必须省略return不写,同时必须省略“;”不写3)参数类型可以省略不写4)如果只有一个参数,参数类型可以省略,同时()也可以省略
也就是说上面的代码只有一行,我们可以进一步改写,首先去掉大括号,去掉分号,看到说明(2),我们需要去掉return,同时分号去掉,再接着省略参数类型:
publicclassLambdaDemo1 { publicstaticvoidmain(String[] args) { List<Student>lists=newArrayList<>(); Students1=newStudent("小花",16,"女"); Students2=newStudent("小红",18,"女"); Students3=newStudent("小乐",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); privateStringname; privateintage; privateStringsex; //省略get/set } }
对forEach的简化:
publicstaticvoidmain(String[] args){ List<String>names=newArrayList<>(); names.add("ab"); names.add("bc"); names.add("xiao"); nams.forEach(newComsumer<String>(){ publicvoidaccpet(Strings){ System.out.println(s); } }); }
进行改写:
publicstaticvoidmain(String[] args){ List<String>names=newArrayList<>(); 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流的一些学习
筛选操作:
publicstaticvoidmain(String[] args){ //需求:从集合中筛选出现所有长度为3,且姓张的同志,同时对同名同姓的进行虑重List<String>list=newArrayList<>(); 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));