首先说下Lambda表达式的优点和缺点:
优点:
1:简洁
2:易并行计算,特别适合便利结果,循环计算数值或者赋值的时候很方便
缺点:
1:若不用并行运算,很多时候计算方式速度没有传统的For循环快。
2:不容易使用Debug模式调试
3:再Lamdba语句中直接强制转换不方便
4:不可以再foreach中修改外面的值
Lambda表达式的基本语法:(parameters) -> expression 或 (parameters) -> { statements; }
解释:(parameters)这个参数名字可以自定义,但是一般要做到见名之意, -> 这个必须有 (parameters) -> expression 或 (parameters)
->{ 方法体}
例子:
List<Map<String,Object>> sevenTIME= jdbcTemplate.queryForList ( " SELECT * FROM operation_log_details );
sevenTIME.forEach((ss)->{ //遍历结果集 ss 类似于for循环中的循环值
System.out.println(ss);//循环打印结果集
//具体有关联的逻辑代码
});
1.替代匿名内部类
毫无疑问,lambda表达式用得最多的场合就是替代匿名内部类,而实现Runnable接口是匿名内部类的经典例子。lambda表达式的功能相当强大,用()->就可以代替整个匿名内部类!请看代码:
如果使用匿名内部类:
@Test
public void oldRunable() {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("The old runable now is using!");
}
}).start();
}
而如果使用lambda表达式
@Test public void runable() {
new Thread(() -> System.out.println("It's a lambda function!")).start();
}
2.使用lambda表达式对集合进行迭代
Java的集合类是日常开发中经常用到的,甚至说没有哪个java代码中没有使用到集合类。。。而对集合类最常见的操作就是进行迭代遍历了。请看对比:
public void iterTest() {
List<String> languages = Arrays.asList("java","scala","python");
//before java8
for(String each:languages) {
System.out.println(each);
}//传统的循环方式 方式1
//after java8
languages.forEach(x -> System.out.println(x));//结果集同上 方式2
languages.forEach(System.out::println);//结果集同上 方式3
}
3.用lambda表达式实现map
@Test public void mapTest() {
List<Double> cost = Arrays.asList(10.0, 20.0,30.0); cost.stream().map(x -> x + x*0.05).forEach(x -> System.out.println(x));
}
map函数可以说是函数式编程里最重要的一个方法了。map的作用是将一个对象变换为另外一个。在我们的例子中,就是通过map方法将cost增加了0,05倍的大小然后输出
4.用lambda表达式实现map与reduce
既然提到了map,又怎能不提到reduce。reduce与map一样,也是函数式编程里最重要的几个方法之一。。。map的作用是将一个对象变为另外一个,而reduce实现的则是将所有值合并为一个,请看:
@Test public void mapReduceTest() {
List<Double> cost = Arrays.asList(10.0, 20.0,30.0); double allCost = cost.stream().map(x -> x+x*0.05).reduce((sum,x) -> sum + x).get(); System.out.println(allCost);
}
最终的结果为:
63.0
如果我们用for循环来做这件事情:
@Test public void sumTest() {
List<Double> cost = Arrays.asList(10.0, 20.0,30.0); double sum = 0;
for(double each:cost) {
each += each * 0.05;
sum += each;
} System.out.println(sum);
}
5.filter操作
filter也是我们经常使用的一个操作。在操作集合的时候,经常需要从原始的集合中过滤掉一部分元素。
@Test public void filterTest() {
List<Double> cost = Arrays.asList(10.0, 20.0,30.0,40.0);
List<Double> filteredCost = cost.stream().filter(x -> x > 25.0).collect(Collectors.toList()); filteredCost.forEach(x -> System.out.println(x));
}
最后的结果:
30.0
40.0
函数式接口(Functional Interfaces),它表示只有一个抽象方法的接口,可以用来指向Lambda表达式。例如:
Consumer c = (s) -> System.out.println(s);
6.与函数式接口Predicate配合
除了在语言层面支持函数式编程风格,Java 8也添加了一个包,叫做 java.util.function。它包含了很多类,用来支持Java的函数式编程。其中一个便是Predicate,使用 java.util.function.Predicate 函数式接口以及lambda表达式,可以向API方法添加逻辑,用更少的代码支持更多的动态行为。Predicate接口非常适用于做过滤。
java.util.function详解:
-
Function<T, R>:接受一个参数T,返回结果R
-
Predicate<T>:接受一个参数T,返回boolean
-
Supplier<T>:不接受任何参数,返回结果T
-
Consumer<T>:接受一个参数T,不返回结果
-
UnaryOperator<T>:继承自Function<T, T>,接受一个参数T,返回相同类型T的结果
-
BiFunction<T, U, R>:接受两个参数T和U,返回结果R
-
BinaryOperator<T>:继承自BiFunction<T, T, T>,接受两个相同类型T的参数,返回相同类型T的结果
-
Runnable:实际上是不接受任何参数,也不返回结果
-
Comparable<T>:实际上是接受两个相同类型T的参数,返回int
-
Callable<V>:不接受任何参数,返回结果V
例子:
public static void main(String[] args) {
List<String> languages = Arrays.asList("Java","Python","scala","Shell","R");
System.out.println("Language starts with J: ");
filterTest(languages,x -> x.startsWith("J"));
System.out.println("\nLanguage ends with a: ");
filterTest(languages,x -> x.endsWith("a"));
System.out.println("\nAll languages: ");
filterTest(languages,x -> true);
System.out.println("\nNo languages: ");
filterTest(languages,x -> false);
System.out.println("\nLanguage length bigger three: ");
filterTest(languages,x -> x.length() > 4);
}
最后的输出结果:
Language starts with J:
Java
Language ends with a:
Java
scala
All languages:
Java
Python
scala
Shell
R
No languages:
Language length bigger three:
Python
scala
Shell
forEach+Lambda 表达式遍历Map和List
============Java8之前的方式==========
Map<String, Integer> items = new HashMap<>();
items.put("A", 10);
items.put("B", 20);
items.put("C", 30);
items.put("D", 40);
items.put("E", 50);
items.put("F", 60);
for (Map.Entry<String, Integer> entry : items.entrySet()) {
System.out.println("Item : " + entry.getKey() + " Count : " + entry.getValue());
}
============forEach + Lambda表达式==========
Map<String, Integer> items = new HashMap<>();
items.put("A", 10);
items.put("B", 20);
items.put("C", 30);
items.put("D", 40);
items.put("E", 50);
items.put("F", 60);
items.forEach((k,v)->System.out.println("Item : " + k + " Count : " + v));
items.forEach((k,v)->{
System.out.println("Item : " + k + " Count : " + v);
if("E".equals(k)){
System.out.println("Hello E");
}
});
二遍历List:
============Java8之前的方式==========
List<String> items = new ArrayList<>();
items.add("A");
items.add("B");
items.add("C");
items.add("D");
items.add("E");
for(String item : items){
System.out.println(item);
}
============forEach + Lambda表达式==========
List<String> items = new ArrayList<>();
items.add("A");
items.add("B");
items.add("C");
items.add("D");
items.add("E");
//输出:A,B,C,D,E
items.forEach(item->System.out.println(item));
//输出 : C
items.forEach(item->{
if("C".equals(item)){
System.out.println(item);
}
});