一,前言
在上一篇博客中,小编向大家抛转引玉,简单说明了[ Java8 ],其实Java 8在2014年3月18日,就发布了。可以说程序员都很激动,而我就不知道,慢慢的接触了,就发现这个东西还真是不错。
二,为什么使用Lambda表达式?
第一次接触Lambda表达式的时候,是在学习中.net的lambda表达式,用于写入sql语句。当时自己也是通过看视频接触的,还记得当时自己也是学Linq语句,例如:
1.选择语句:books.Select(p => new {p.Title,p.UnitPrice,p.Author}); //需用匿名方式
2. where语句:books.Where(p => p.UnitPrice == 100 && p.Title =” ABC”);
现在在java8中,汇集了众家的所长,把lambda表达式融合过来了。可以说真是棒。什么是Lambda表达式呢?Lambda表达式就是一个匿名函数(匿名函数就是没有实际名字的函数),我们可以把LAMBDA表达式理解为一段可以传递的代码。可以写出更简洁,更灵活的代码。作为一种更紧凑的代码风格,使得java的的语言表达能力得到了提升。那拉姆达表达式的格式是什么样的呀?
lambda表达式的基础语法:Java8引入一个新的操作符 - >
该操作符叫做箭头操作符,箭头把操作符分成两部分。左侧:lambda表达式的参数列表; 右侧:lambda表达式式中所需执行的功能,即lambda体
三,10个演示足够你使用Lambda表达式
3.1无参数,无返回值6行变1行
@Test
public void test1(){
//第一种 经典型
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("I Love Java!!");
}
}).start();
System.out.println("----------------------------------------------");
//第二种 lambda型
new Thread(()->System.out.println("I Love Java!!")).start();
}
结果:
3.2一个参数,无返回值
@Test
public void test2(){
happy(1000,(x)->System.out.println("你们爱的java喜欢消费,喜欢大保健,平均:"+x+"元"));
}
/**
* 调用消费型接口
* @param money
* @param con
*/
public void happy(double money, Consumer<Double> con){
con.accept(money);
}
结果:
说明:如果只有一个参数,小括号可以省略不写’happy(1000,x - > System.out.println(“你们爱的java喜欢消费,喜欢大保健,平均:”+ x +“元“)); `如果lambda中只有一条语句,返回和大括号可以省略不写.
3.3 有两个以上的参数,有返回值,并且有多条语句
多条语句用{}括起来。如果lambda体只有一条一条语句 ,return和大括号都可以省略。
@Test
public void testCount(){
Long t1= 5L;
Long t2=9L;
long count = count(t1, t2, (l1, l2) -> l1 + l2);
System.out.println(count);
System.out.println("---------------------------------------");
long count1 = count(t1, t2, (l1, l2) -> l1 * l2);
System.out.println(count1);
}
结果:
四、实例
4.1 lambda表达式实现Runnable接口
java8之前runnable接口实现方法用4行代码,使用lambda表达式只需要一行代码:
// Java 8之前:
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Before Java8, too much code for too little to do");
}
}).start();
//Java 8方式:
new Thread( () -> System.out.println("In Java8, Lambda expression rocks !!") ).start();
4.2 使用lambda表达式代替增强for循环
做java的,肯定接触过集合类,接触过list。最常见的就是迭代、遍历其中的所有元素。java8之前的所有循环代码是顺序的,可以对其元素进行并行处理。如果想做并行过滤就要自己写代码。通过引入lambda表达式和默认方法,将做什么和怎么做的问题分开了,这意味着Java集合现在知道怎样做迭代,并可以在API层面对集合元素进行并行处理。
// Java 8之前:
List features = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API");
for (String feature : features) {
System.out.println(feature);
}
// Java 8之后:
List features = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API");
features.forEach(n -> System.out.println(n));
// 使用Java 8的方法引用更方便,方法引用由::双冒号操作符标示,
// 看起来像C++的作用域解析运算符
features.forEach(System.out::println);
4.3 lambda表达式使用Map 和Reduce
Map 映射,接收Lambda,将元素转换成新的集合。接收一个函数作为参数,该函数会被应用到每一个元素上,并将其映射为一个新的元素。
Reduce可以将流中元素反复结合起来,得到一个值。
List<Employee> emps = Arrays.asList(
new Employee(101,"张三",18,9999.99),
new Employee(102,"李四",18,4444.66),
new Employee(103,"王五",14,3000.99),
new Employee(104,"赵六",55,20000.99),
new Employee(105,"田七",66,55555.55),
new Employee(106,"周八",77,99.99)
);
@Test
public void test3(){
//map 取出emps list 中所有名字,并打印出来
emps.stream().map(Employee::getName).forEach(System.out::println);
//map 把emps集合中所有人的名字取出来,放到新的list中
List<String> collect = emps.stream().map(Employee::getName).collect(Collectors.toList());
System.out.println("------------------------------------");
//reduce 求和
List<Integer> list = Arrays.asList(1, 2, 3, 4, 55, 56, 7, 78, 8, 9);
Integer sum = list.stream().reduce(0, (x, y) -> x + y);
System.out.println(sum);
System.out.println("------------------------------------");
//map reduce 计算所有工人的薪资总和
Optional<Double> optional = emps.stream().map(Employee::getSalary).reduce(Double::sum);
System.out.println(optional.get());
}
Map和Reduce操作是函数式编程的核心操作,因为其功能,reduce 又被称为折叠操作。另外,reduce 并不是一个新的操作,你有可能已经在使用它。SQL中类似 sum()、avg() 或者 count() 的聚集函数,实际上就是 reduce 操作,因为它们接收多个值并返回一个值。流API定义的 reduceh() 函数可以接受lambda表达式,并对所有值进行合并。IntStream这样的类有类似 average()、count()、sum() 的内建方法来做 reduce 操作,也有mapToLong()、mapToDouble() 方法来做转换。这并不会限制你,你可以用内建方法,也可以自己定义。在这个Java 8的Map Reduce示例里,我们首先对所有价格应用 12% 的VAT,然后用 reduce() 方法计算总和。
// 为每个订单加上12%的税
// 老方法:
List costBeforeTax = Arrays.asList(100, 200, 300, 400, 500);
double total = 0;
for (Integer cost : costBeforeTax) {
double price = cost + .12*cost;
total = total + price;
}
System.out.println("Total : " + total);
// 新方法:
List costBeforeTax = Arrays.asList(100, 200, 300, 400, 500);
double bill = costBeforeTax.stream().map((cost) -> cost + .12*cost).reduce((sum, cost) -> sum + cost).get();
System.out.println("Total : " + bill);
4.4 过滤一个String列表
流提供filter方法,过滤。
过滤是Java开发者在大规模集合上的一个常用操作,而现在使用lambda表达式和流API过滤大规模数据集合是惊人的简单。流提供了一个 filter() 方法,接受一个 Predicate 对象,即可以传入一个lambda表达式作为过滤逻辑。下面的例子是用lambda表达式过滤Java集合,将帮助理解。
// 创建一个字符串列表,每个字符串长度大于2
List<String> filtered = strList.stream().filter(x -> x.length()> 2).collect(Collectors.toList());
System.out.printf("Original List : %s, filtered list : %s %n", strList, filtered);
4.5 去重 distinct
流的 distinct() 方法来对集合进行去重:
// 用所有不同的数字创建一个正方形列表
List<Integer> numbers = Arrays.asList(9, 10, 3, 4, 7, 3, 4);
List<Integer> distinct = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());
System.out.printf("Original List : %s, Square Without duplicates : %s %n", numbers, distinct);
输出:
Original List : [9, 10, 3, 4, 7, 3, 4], Square Without duplicates : [81, 100, 9, 16, 49]
4.6 计算集合的最大值、最小值、总和以及平均值
IntStream、LongStream 和 DoubleStream 等流的类中,有个非常有用的方法叫做 summaryStatistics() 。可以返回 IntSummaryStatistics、LongSummaryStatistics 或者 DoubleSummaryStatistic s,描述流中元素的各种摘要数据。在本例中,我们用这个方法来计算列表的最大值和最小值。它也有 getSum() 和 getAverage() 方法来获得列表的所有元素的总和及平均值。
//获取数字的个数、最小值、最大值、总和以及平均值
List<Integer> primes = Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19, 23, 29);
IntSummaryStatistics stats = primes.stream().mapToInt((x) -> x).summaryStatistics();
System.out.println("Highest prime number in List : " + stats.getMax());
System.out.println("Lowest prime number in List : " + stats.getMin());
System.out.println("Sum of all prime numbers : " + stats.getSum());
System.out.println("Average of all prime numbers : " + stats.getAverage());
输出:
Highest prime number in List : 29
Lowest prime number in List : 2
Sum of all prime numbers : 129
Average of all prime numbers : 12.9
五、小结
java 越来越好!
近些年来,java更新的越来越好。通过新特性的学习,以后就可以更加高效率的写代码了。