1、java8介绍
(1)概念
是Java语言历史上变化最大的一个版本,其调整java编程向函数式风格迈进,不会对老版本产生影响
(2)优势
速度鞥更快
永久帯取消
HashMap的优化
ConcurrentHashMap的使用
堆内存的永久区取消,取而代之的是元空间(物理内存),将方法区从永久区中剥离了出来
代码更少
强大的Stream API
便于并行
最大化减少空指针异常
2、Lambda表达式介绍
为什么需要Lambda表达式?
(1)在java中无法将函数作为参数传递给一个方法,也无法声明返回一个函数的方法,利用Lambda表达式可以写出更加简洁、灵活的代码
(2)在JS中,函数参数是一个函数,返回值是另一个函数的情况是常见的,js是一门非常典型的函数式语言
3、lambda表达式
(1)匿名内部类: 为按钮注册事件监听器
public static voidmain(String[] args) {
JFrame jFrame=new JFrame("My JFrame");
JButton jButton=new JButton("My JButton");
jButton.addActionListener(newActionListener() {
@Overridepublic voidactionPerformed(ActionEvent e) {
System.out.println("Button Pressed!!");
}
});
jFrame.add(jButton);
jFrame.pack();
jFrame.setVisible(true);
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
可以用lambda表达式代替:
用lambda表达式代替:
public static voidmain(String[] args) {
JFrame jFrame=new JFrame("My JFrame");
JButton jButton=new JButton("My JButton");
jButton.addActionListener(Event->System.out.println("Button Pressed!!"));
jFrame.add(jButton);
jFrame.pack();
jFrame.setVisible(true);
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
(2)例二:
//原来的匿名内部类
public voidtest1(){
Comparator com = new Comparator(){public intcompare(Integer o1,Integer o2){returnInteger.compare(o1,o2);
}
};
TreeSet ts = new TreeSet<>(com);
}//Lambda表达式
public voidtest2(){
Comparator com = (x,y)->Integer.compare(x,y);
TreeSet ts = new TreeSet<>(com);
}
(3)例三
在处理Set集合的时候,在对自定义类的操作中需要创建比较器,如果一开始的需求是计算分数大于500的学生信息,然后是计算分数大于600的学生信息。如果使用的是内明内部类仅仅修改判断语句的条件即可,代码的冗余度极高。使用lambda表达式可以减少代码量
4、函数式接口
(1)一个接口里面只有一个抽象的方法
(2)要求:
*
The type is an interface type and not an annotation type, enum, or class.* The annotated type satisfies the requirements of a functional interface.(3)如果在某一个接口上声明了@FunctionalInterface注解,那么编译器就会按函数式接口的定义来要求该接口
@FunctionalInterfacepublic interface Consumer {
(4)如果一个接口只有一个抽象方法,但我们并没有添加@FunctionalInterface注解,那么编译器依旧会将该接口当做函数式接口
(5)如果一个接口声明了一个抽象方法,但是该抽象方法重写了Object类的方法,那么不会使得接口的抽象方法数量加一:
书写一个接口:
修改为: 错误消失
匿名内部类方式:
@FunctionalInterfaceinterfaceMyInterface {voidtest1();
String toString();
}public classtest2 {public voidMytest(MyInterface myInterface) {
System.out.println("111");
myInterface.test1();
System.out.println("2222");
}public static voidmain(String[] args) {
test2 test=newtest2();
test.Mytest(newMyInterface() {
@Overridepublic voidtest1() {
System.out.println("mytest");
}
});
}
}
lambda表达式:
public static voidmain(String[] args) {
test2 test=newtest2();
test.Mytest(()->{
System.out.println("mytest");
});
}
执行结果是一样的:
111mytest2222
5、默认方法:在接口里面定义的实现过的方法
在 interface Iterable 中有如下方法:实现该接口的类默认继承该方法
default void forEach(Consumer super T>action) {
Objects.requireNonNull(action);for (T t : this) {
action.accept(t);
}
}
6、凡是将函数式接口作为函数参数的时候,都可以用lambar表达式的方式进行替换
public classTest1 {public static voidmain(String[] args) {
List list= Arrays.asList(1,2,45,32,234,3);
list.forEach(new Consumer() {
@Overridepublic voidaccept(Integer integer) {
System.out.println(integer);
}
});
}
}
public static voidmain(String[] args) {
List list= Arrays.asList(1,2,45,32,234,3);
list.forEach(i->{
System.out.println(i);
});
}
没有加类型声明是因为存在类型推断
public static voidmain(String[] args) {
List list= Arrays.asList(1,2,45,32,234,3);
list.forEach((Integer i)->{
System.out.println(i);
});
}
7、lambda表达式的作用
(1)Lambda表达式为java添加了缺失的函数式编程特性,使我们能将函数当做一个公民来看待
(2)在将函数作为一等公民的语言(python)中,lanbda表达式的类型是函数。但是在java中,它是对象,他们必须依赖于一类特别的对象模型(函数式接口)