一、函数式编程
理解FunctionalInterface(函数式接口)是学习Java8 Lambda表达式的关键所在。FI的定义其实很简单:任何接口,如果只包含唯一 一个抽象方法,那么它就是一个FI。为了让编译器帮助我们确保一个接口满足FI的要求(也就是说有且仅有一个抽象方法),Java8提供了@FunctionalInterface注解。
简单例子:
1.8之前使用匿名内部类
public static void main(String[] args) {
//JDK1.8版本之前的做法
Consumer<Integer> con = new Consumer<Integer>() {
@Override
public void accept(Integer t) {
System.out.println(t);
}
};
//调用方法
con.accept(3);
}
在1.8以后引入函数式的编程可以这样写
public static void main(String[] args) {
//第一种写法:
Consumer<Integer> con = (param) -> {System.out.println(param);};
//第二种写法:
Consumer<Integer> con1 = (param) -> System.out.println(param);
//第三种写法:
Consumer<Integer> con2 = System.out::println;
con2.accept(3);
}
函数式编程接口都只有一个抽象方法,因此在采用这种写法时,编译器会将这段函数编译后当作该抽象方法的实现,如果接口有多个抽象方法,编译器就不知道这段函数应该是实现哪个方法的了。
二、lamda表达式
例
interface Message{
public void print(String str);
}
public class TestDemo {
public static void main( String[] args ) {
/**
* 使用的是匿名内部类的方式
*/
Message msg = new Message() {
@Override
public void print( String str ) {
System.out.println(str);
}
};
msg.print("hello world!");
}
interface Message{
public void print(String str);
}
//定义一个统一的接口
public class TestDemo {
public static void main( String[] args ) {
/**
* 使用lambda表达式的方式
*/
Message msg=(s)-> System.out.println(s);
msg.print("hello world!");
}
}
注:
1、 lambda表达式最重要的目的是解决匿名内部类的问题;
2、 想要使用lambda表达式,那么必须以接口为主,而且接口里面只能够定义一个抽象方法。
三、Stream
Stream可以分为串行与并行两种,串行流和并行流差别就是单线程和多线程的执行。
default Stream stream() : 返回串行流
default Stream parallelStream() : 返回并行流
List<Dish> menu = ...
List<String> lowCaloricDishesName = menu.stream()
//筛选出卡路里大于400的
.filter(d -> d.getCalories() < 400)
//抽取名字属性创建一个新的流
.map(Dish::getName)
//这个流按List类型返回
.collect(toList());
filter 和 map 操作被称为中间操作,中间操作会返回一个新的流,而 collect 则被称为终端操作只有终端操作才会让整个流执行并关闭。也就是说 每个流只能遍历一次 ,因为collect以后这个流就已经关闭了。
四、接口中可以定义方法体
注:
(1)如果多个接口定义了同样的静态方法,
即使存在实现类,同时实现多个接口,仍然是不可使用实现类名调用接口的方法
(2)如果多个接口定义了同样的默认方法
实现类实现多个接口时,必须重写掉默认方法,否则编译失败。
在接口中可以定义实现的方法体是java8的一大特性,可以定义多个静态或者默认的方法,静态必须加上static,默认方法必须加上default关键字。
五、hashmap的变化
Java8中HashMap的最大不同是,它利用了红黑树,即由数组+链表+红黑树组成。除了添加,红黑树效率慢,其他的情况都比链表快。jdk1.8把头插法换成了尾插法(避免形成环)。
ConcurrentHashMap:现在把重入锁变成了CAS算法(无锁),提高效率。
具体变化还有很多。。。