1.接口中的static方法不能被继承,也不能被实现类调用,只能被自身调用,但是静态变量会被继承 ,实现类可以直接调用接口中的default方法,default方法被继承时,可以被子接口覆写,如果一个类实现了多个接口,且这些接口中无继承关系,这些接口中若有相同的(同名,同参数)的default方法,则接口实现类会报错,接口实现类必须通过特殊语法指定该实现类要实现那个接口的default方法
public interface DefalutTest {
static int a =5;
default void defaultMethod(){
System.out.println("DefalutTest defalut 方法");
}
int sub(int a,int b);
static void staticMethod() {
System.out.println("DefalutTest static 方法");
}
}
二、Lambda 表达式
口诀: 左右遇一括号省, (左边是单参数 可以省小括号,右边是一行代码的可以省略大括号)
左侧推断类型省(左侧的参数类型可以省略不写,java8可以通过上下文推断出参数类型)
lambda 需要函数式接口的支持,
函数式接口:接口中只有一个抽象方法, 可以用@FunctionalInterface 来修饰
四大核心函数函数型接口 :
1. Consumer<T>:消费型接口
void accept(T t);
2.Supplier <T> :供给型接口
T get();
3.Function<T>:函数型接口
R apply(T t);
4 .Predicate<T> :断言型接口
boolean test(T t);
>>>>>>>如果lambda体中的内容有方法已经实现了,就可以用:方法引用
有3种语法格式
对象::实例方法名
类::静态方法名
类::实例方法名
Consumer<String > con = x->system.out.println(x);
PrintStream ps = System.out;
Consumer<String> con1 = ps::println
con1.accept("aaaaaa");
前提条件是 被引用的方法 println() 参数列表和返回值类型 跟Consumer中accept方法的参数列表和返回值类型一致
都是返回空 参数都是一个
注意:
1.Lambda 体中调用方法的参数列表与返回值类型,要与函数式接口中的抽象方法的函数列表和返回值类型保持一致
2.若lambda参数列表中的第一个参数是实例方法的调用者,而第二个参数是实例方法的参数时,可以使用class Name::method
>>>>>>>>>>>>>>构造器引用
Supplier<Employee> sup= ()->new Employee();
Supplier<Emloyee> sup = Employee:new ;
注意:如果Employee 有多个构造器,根据Supplier的get()方法时无参的方法,所以 引用的Employee的构造器也是无参的
需要调用的构造器的参数列表要与函数是接口中抽象方法的参数列表保持一致
Type[] ::new
(参数1,参数2…)表示参数列表;->表示连接符;{}内部是方法体
1、=右边的类型会根据左边的函数式接口类型自动推断;
2、如果形参列表为空,只需保留();
3、如果形参只有1个,()可以省略,只需要参数的名称即可;
4、如果执行语句只有1句,且无返回值,{}可以省略,若有返回值,则若想省去{},则必须同时省略return,且执行语句也保证只有1句;
5、形参列表的数据类型会自动推断;
6、lambda不会生成一个单独的内部类文件;
7、lambda表达式若访问了局部变量,则局部变量必须是final的,若是局部变量没有加final关键字,系统会自动添加,此后在修改该局部变量,会报错;
public interface LambdaTest {
abstract void print();
}
public interface LambdaTest2 {
abstract void print(String a);
}
public interface DefalutTest {
static int a =5;
default void defaultMethod(){
System.out.println("DefalutTest defalut 方法");
}
int sub(int a,int b);
static void staticMethod() {
System.out.println("DefalutTest static 方法");
}
}
public class Main {
public static void main(String[] args) {
//匿名内部类--java8之前的实现方式
DefalutTest dt = new DefalutTest(){
@Override
public int sub(int a, int b) {
// TODO Auto-generated method stub
return a-b;
}
};
//lambda表达式--实现方式1
DefalutTest dt2 =(a,b)->{
return a-b;
};
System.out.println(dt2.sub(2, 1));
//lambda表达式--实现方式2,省略花括号
DefalutTest dt3 =(a,b)->a-b;
System.out.println(dt3.sub(5, 6));
//测试final
int c = 5;
DefalutTest dt4 =(a,b)->a-c;
System.out.println(dt4.sub(5, 6)); //内部类使用局部变量,并试图修改,报错,内部类引用局部变量必须加final
//无参方法,并且执行语句只有1条
LambdaTest lt = ()-> System.out.println("测试无参");
lt.print();
//只有一个参数方法
LambdaTest2 lt1 = s-> System.out.println(s);
lt1.print("有一个参数");
}
}
1、引用实例方法:
语法:
<函数式接口> <变量名> = <实例>::<实例方法名>
//调用
<变量名>.接口方法([实际参数...])
- 将调用方法时的传递的实际参数,全部传递给引用的方法,执行引用的方法;
public class Main {
public static void main(String[] args) {
LambdaTest2 lt1 = s-> System.out.println(s);
lt1.print("有一个参数");
//改写为:
LambdaTest2 lt2 = System.out::println;
lt2.print("实例引用方式调用");
}
}
2、引用类方法:
语法:
<函数式接口> <变量名> = <类>::<类方法名称>
//调用
<变量名>.接口方法([实际参数...])
- 将调用方法时的传递的实际参数,全部传递给引用的方法,执行引用的方法;
三. hashmap升级
HashMap中链长度大于8时采取红黑树的结构存储。
红黑树,除了添加,效率高于链表结构。
concurrentMap
Jdk1.7时隔壁级别CocnurrentLevel(锁分段机制)默认为16。
JDK1.8采取了CAS算法
Jdk1.8没有永久区,取而代之的是MetaSpace元空间,用的是物理内存。