由于项目中使用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));