Java Lambda表达式
- 创建线程
//普通写法 Thread thread = new Thread(new Runnable() { @Override public void run() { //业务代码 } }); thread.start(); //lambda Thread lamThread = new Thread(() -> { //System.out.println("业务代码"); });
- 排序
List<String> arrayList = Arrays.asList(new String[]{"b","c","a","f"});//匿名类写法 Collections.sort(arrayList, new Comparator<String>() { @Override public int compare(String o1, String o2) { return o1.compareTo(o2); } }); //lambda表达式 -倒序 ([f, c, b, a]) Collections.sort(arrayList,Comparator.comparing(String::toString).reversed()); //lambda表达式 -正序 Collections.sort(arrayList,Comparator.comparing(String::toString)); System.out.println(arrayList);
- 循环
String[] atp = {"Rafael Nadal", "Novak Djokovic", "Stanislas Wawrinka", "David Ferrer","Roger Federer", "Andy Murray","Tomas Berdych", "Juan Martin Del Potro"}; List<String> players = Arrays.asList(atp); players.forEach(player->{ });
1.1lambda表达式语法
1.1.1lambda表达式的一般语法
(Type1 param1, Type2 param2, ..., TypeN paramN) -> { statment1; statment2; //............. return statmentM; }
这是lambda表达式的完全式语法,后面几种语法是对它的简化
1.1.2单参数语法
param1 -> { statment1; statment2; //............. return statmentM; }
当lambda表达式的参数个数只有一个,可以省略小括号
例如:将列表中的字符串转换为全小写
List<String> proNames = Arrays.asList(new String[]{"Ni","Hao","Lambda"}); List<String> lowercaseNames1 = proNames.stream().map(name -> {return name.toLowerCase();}).collect(Collectors.toList());
1.1.3单语句写法
param1 -> statment
当lambda表达式只包含一条语句时,可以省略大括号、return和语句结尾的分号
例如:将列表中的字符串转换为全小写
List<String> proNames = Arrays.asList(new String[]{"Ni","Hao","Lambda"}); List<String> lowercaseNames2 = proNames.stream().map(name -> name.toLowerCase()).collect(Collectors.toList());
1.1.4方法引用写法
Class or instance :: method
例如:将列表中的字符串转换为全小写
List<String> proNames = Arrays.asList(new String[]{"Ni","Hao","Lambda"}); List<String> lowercaseNames3 = proNames.stream().map(String::toLowerCase).collect(Collectors.toList());
1.2lambda表达式可使用的变量
- 成员变量(lambda的外部变量)
- 局部变量(lambda的内部变量)
- 传递变量(lambda的传递参数)
lambda表达式可以访问给它传递的变量,访问自己内部定义的变量,同时也能访问它外部的变量。
成员变量在被lambda表达式引用后,编译器会隐式的把它当成final来处理。
以前Java的匿名内部类在访问外部变量的时候,外部变量必须用final修饰。现在java8对这个限制做了优化,可以不用显示使用final修饰,但是编译器隐式当成final来处理。
String merVariable = "merber :"; List<String> proStrs = Arrays.asList(new String[]{"Hello","Hao","Lambda"}); List<String> execStrs = proStrs.stream().map(passingVariable -> { Long locVariable = System.currentTimeMillis(); //merVariable += "merber";不允许,在lambda表达式中成员变量(及lambda的外部变量)默认被final修饰,不支持改变 passingVariable += "passing";//允许 locVariable += 10;//允许 return merVariable + passingVariable + " -----:" + locVariable; }).collect(Collectors.toList()); execStrs.forEach(System.out::println);
1.3lambda表达式中的this概念
在lambda中,this不是指向lambda表达式产生的那个SAM对象,而是声明它的外部对象。
public void testVariable(){ List<String> proStrs = Arrays.asList(new String[]{"Hello","Hao","Lambda"}); proStrs.stream().map(passingVariable -> { System.out.println(this.getClass().getName()); return 0; }); }
输出结果:
com.rht.test.testVariable
com.rht.test.testVariable
com.rht.test.testVariable
2.方法引用和构造器引用
2.1方法引用
- objectName::instanceMethod
- ClassName::staticMethod
- ClassName::instanceMethod
前两种方式类似,等同于把lambda表达式的参数直接当成instanceMethod|staticMethod的参数来调用。比如System.out::println等同于x->System.out.println(x);Math::max等同于(x, y)->Math.max(x,y)。
最后一种方式,等同于把lambda表达式的第一个参数当成instanceMethod的目标对象,其他剩余参数当成该方法的参数。比如String::toLowerCase等同于x->x.toLowerCase()。
可以这么理解,前两种是将传入对象当参数执行方法,后一种是调用传入对象的方法。
public static void testMethod2(){ List<String> proStrs = Arrays.asList(new String[]{"Hello","Hao","Lambda"}); List<String> newList = new ArrayList<>(); proStrs.forEach(System.out::println); proStrs.forEach(s->newList.add(lambdaTest.a(s))); newList.forEach(System.out::println); } public static String a(String a){ a += "zj"; return a; }
*双冒号只适合单语句,如上语句:
proStrs.forEach(s->newList.add(lambdaTest.a(s)));
*不能改成
proStrs.forEach(newList.add(lambdaTest::a));
2.2构造器引用
构造器引用语法如下:ClassName::new,把lambda表达式的参数当成ClassName构造器的参数 。例如BigDecimal::new等同于x->new BigDecimal(x)
3.Stream语法
posted on 2019-01-23 12:02 Best_Wishes 阅读(156) 评论(0) 编辑 收藏 举报