起因:今天朋友跟我讲起面试时被面试官问到流式编程,我们俩都是知道这个java8的新特性,但是之前也一直没用过,所以谈话就止步于我知道这么个事的程度,想起在之前的公司看到有人这么写也没当一回事,自己就是简单看了一下,结果很长时间不用又忘了,今天就想好好学习一下,看了一些教学视频,想主要关注的特性就是两点Lambda表达式和流式编程,剩下的以后遇到再总结。
一、Lambda表达式
概述:Lambda表达式是一种匿名函数(不是匿名内部类),简单的说他是没有声明方法的,即没有访问修饰符、返回值声明和名字。在使用中使代码更简洁。
语法:(paramters)->{statements};
下面看一段代码进行比较
public class LamadaTest {
public static void main(String[] args) {
String str1 = "普通实现接口";
Fu fu1 = new Fu() {
@Override
public void add(String str) {
System.out.println(str);
}
};
fu1.add(str1);
String str2 = "Lambda表达式实现";
Fu fu2 = (str)->{
System.out.println(str2);
};
fu2.add(str2);
}
}
interface Fu {
void add(String str);
}
代码功能:实现并重写Fu接口的add方法。并且调用输出结果。
通过Lambda表达是可以看出代码简化了很多。
注意一点:Lambda表达式只能用在只有一个抽象方法的接口上。比如:Fu接口除了定义add方法,又定义了一个add2,Lambda将不再适用。但这个接口可以有其它非抽象方法:比如静态方法。
Lambda表达式的一些简写特性:
应用:通过了解Lambda表达式的还是有很多限制性的,在实际应用中感觉并不是能随心所欲的用到,但是JDK内置函数接口,使得Lambda表达式的运用更加方便、高效。这种接口叫函数式接口
二、函数式接口
概述:接口中只能有一个抽象方法,其他的可以有default、static、Object里继承的方法等。JDK8专门提供了@FunctionalInterface注解,用来进行编译检查。
常用的函数式接口:Comparable、Callable、Runnable
三、流式编程
介绍:Stream(流式编程)与java.io流是完全不同的概念。它是对容器对象(集合)功能的增强,它专注于对容器对象进行各种非常便利、高效的聚合操作或者大批量数据操作。
用Stream写了一段简单的对list进行排序、去重代码:
public class LambdaTest5 {
public static void main(String[] args) {
List<Integer> list1 = new ArrayList<>();
Collections.addAll(list1, 2,10,11,3,4,6,1,2,3);
// 使用流式编程对list进行去重和排序
// 【1】获取Strea对象
Stream<Integer> stream = list1.stream();
// 【2】中间操作去重 结果:2,10,11,3,4,6,1,
stream = stream.distinct();
// .sorted() // 正序排序
// .sorted((x,y)->{return Integer.compare(x,y);})//降序排序
// .limit(4) //取集合中前4个
// .skip(2) //跳过前2个
// .map(x->x+5) //每一个数+5
// .filter(x->{
// if(x>=20){
// return true;
// }
// return false;
// });
// 【3】终止操作
stream.forEach(x-> System.out.print(x + ","));
System.out.println();
}
}
可以看出流式编程一共分为三步:
1.获取Stream对象。
2.中间操作(对list中的每一个值进行操作)。
其中比较重要的:(1)去重 ->distinct()
(2)排序 ->sorted()
(3)极限->limit(int)
(4)跳过->skip(int)
(5)操作->map(x)
(6)操作->map(Function(函数式接口))
(7)过滤->filter(Predicate(函数式接口))
3.终止操作。只能执行一次,执行后流关闭,再执行会报错。
其中比较重要的:(1)遍历->forEach(Consumer(函数式接口))
(2)赋值->collect(Collectors.toList())
以下是中间操作和结束操作的相关方法:
四、方法引用
方法引用:方法引用是lambda表达式的一种特殊类型。因此一般应用在lambda表达式中使用
语法一般为:Object::method
方法引用包括以下四种类型:
- 静态方法 (Car::collide)
- 特定对象的实例方法(Car::collide)
- 特定类型的任意对象的实例方法(Car::repair)
- 构造方法(Car::new)
package com.runoob.main;
@FunctionalInterface
public interface Supplier<T> {
T get();
}
class Car {
//Supplier是jdk1.8的接口,这里和lamda一起使用了
public static Car create(final Supplier<Car> supplier) {
return supplier.get();
}
public static void collide(final Car car) {
System.out.println("Collided " + car.toString());
}
public void follow(final Car another) {
System.out.println("Following the " + another.toString());
}
public void repair() {
System.out.println("Repaired " + this.toString());
}
}
详细介绍参照:Java 8 方法引用 | 菜鸟教程