六、泛型、Lambda表达式
1、泛型的概念:
所谓泛型,就是允许在定义类、接口时通过一个标识表示类中某个属性的类型或者是某个方法的返回值及参数类型。这个类型参数将在使用时(例如, 继承或实现这个接口,用这个类型声明变量、创建对象时)确定(即传入实际的类型参数,也称为类型实参)
2、在集合中使用泛型:
- 集合接口或集合类在JDK5.0时都修改为带泛型的结构
- 实例化集合类时,可以指明具体的泛型类型,若没有指明泛型类型,默认是java.lang.Object类型
3、泛型类、泛型接口
- 泛型的类型只能是类,不能为基本数据类型,用到基本数据类型时,使用包装类
- 指明完成后,在集合类或接口中凡是定义类或接口时,内部结构(方法、构造器、属性等)
- 静态方法中不能使用泛型
- 异常类不能声明为泛型类
4、泛型方法
-
在方法中出现了泛型的结构,泛型参数与类的泛型参数没有关系
-
//非静态:泛型方法 public <E> void getE(E e){ }
-
/** * 泛型方法可以是静态的,静态方法是和类一起加载, * 但是静态方法的泛型并不受类上面泛型的影响 */ public static <E>List<E> getEList(E e){ ArrayList<E> es = new ArrayList<>(); es.add(e); return es; }
-
创建对象后就不能再调用静态的泛型方法了,因为此时的静态泛型方法已经在内存中加载完成了但是类型还没有确定,但有我们已经不能进行初始化了,java虚拟机就不暴露出来
5、通配符(?)的使用
/**
* 通配符 ? 的使用
*/
@Test
public void test4(){
List<Object> list1 = null;
List<String> list2 = null;
List<?> list = null;
list = list1;
list = list2;
//List<?> 不能写入数据,除了null可以添加进去
//List<?> 可以读出数据,返回类型为Object
//有限制条件的 ?
// <? extends Person> 只能存放 Person以及Person的子类
// <? super Person> 只能存放 Person以及Person的父类
print(list1);
}
public void print(List<?> list){
Iterator<?> iterator = list.iterator();
while (iterator.hasNext()){
Object obj = iterator.next();
System.out.println(obj);
}
}
6、Lambda表达式(->)
-
Lambda 是一个匿名函数使用它可以写出更简洁、更 灵活的代码。作为一种更紧凑的代码风格,使Java的语言表达能力得到了 提升。
-
格式:
- -> : lambda操作符 或 箭头操作符
- -> 左边 :lambda形参列表(其实就是函数式接口中的抽象方法的形参列表)
- -> 右边 :lambda体(其实就是重写的抽象方法的方法体)
-
使用:
- -> 左边:lambda形参列表的参数类型可以省略(类型推断):如果Lambda形参类表只有一个参数,其括号可以省略,
- -> 右边:lambda体本应该使用一对{}包裹,如果lambda体只有一条执行语句(可能是return语句),{} 和 return语句都可以省略
-
举例:
-
Runnable able1 = new Runnable() { @Override public void run() { System.out.println("able1"); } }; Runnable able2 = () -> System.out.println("able2"); able2.run();
-
Comparable<Integer> com1 = new Comparable<Integer>() { @Override public int compareTo(Integer o) { System.out.println(o); return 0; } }; //Lambda写法 Comparable<Integer> com2 = (o) -> { System.out.println(); return o; };
-
Comparator<Integer> com1 = new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return 0; } }; //Lambda写法 Comparator<Integer> com2 = (o1,o2) -> o1.compareTo(o2); int compare = com2.compare(12, 32); System.out.println(compare); }
-
-
本质:
Lambda的本质函数式接口的实例
7、函数式接口
-
如果一个接口中只有一个抽象方法的接口就被称为函数式接口
-
可以使用@FunctionalInterface来标识一个接口这是一个函数式接口
-
java内置的四大核心函数式接口
函数式接口 参数类型 返回类型 用途 Consumer 消费型接口 T void 对类型为T的对象应用操作,包含方法: void accept(T t) Supplier 供给型接口 无 T 返回类型为T的对象,包含方法:T get() Function<T,R> 函数型接口 T R 对类型为T的对象应用操作,并返回结果。结 果是R类型的对象。包含方法:R apply(T t) Predicate 断定型接口 T boolean 确定类型为T的对象是否满足某约束,并返回 boolean 值。包含方法:boolean test(T t)