Java基础05—泛型和Lambda表达式

本文是学习Java时所记录的学习笔记,本节包含了泛型和Lambda表达式的介绍,是从《疯狂Java讲义第四版》中学习。欢迎留言、私信交流~~

文章目录

      • 泛型
        • 泛型简介
          • 什么是泛型?
        • 泛型具体实现
          • 使用泛型例子
          • 定义泛型接口、类例子
          • 从泛型类派生子类
          • 泛型方法语法和例子
        • 泛型的相关知识
          • 泛型说明
          • 泛型方法
          • 泛型数组
      • Lambda表达式
        • Lambda表达式简介
        • Lambda表达式案例
          • 例子1
          • 例子2
          • 引用类方法
          • 对象实例方法
          • 引用构造器
        • Lambda表达式相关知识
      • 其他
        • 参考资料

泛型

泛型简介

什么是泛型?
  • JAVA5以后,引入了参数化类型(parameterized type)的概念。允许程序在创建集合时指定集合元素的类型,就是List。Java的参数化类型被称为泛型(Generic)。
  • Java7以后新增“菱形”语法。允许在构造器后给一对尖括号(<>)即可。无需完整类似的泛型信息。

泛型具体实现

使用泛型例子
  • 例子
    List strList = new ArrayList();  //只允许strList集合存放字符串对象。
    new  Foo("疯狂学习");  //显式的指定了泛型构造器中的泛型形参类型是String。
    
定义泛型接口、类例子
```
//可以在可使用普通类型的地方使用这种泛型形参。
//List形式是一种特殊的数据类型,可以认为是List类型的子类。
//只定义了一个List,但实际使用时可以产生无数多个List接口。
public interface List{
	void add(E x)
	Interator interator();
}
public interface Iterator{
	E next();
}
public interface ListString extends List{
    void add(String x);
    Interator interator();
}
```
从泛型类派生子类
```
//调用方法需要为所有数据形参传入参数值,而使用类和接口时可以不为泛型形参传入实际的类型参数。
public class A etends Apple;
public class A extends Apple;
```
泛型方法语法和例子
  • 语法
    //T和S为不同的泛型形参声明
    修饰符  返回值类型 方法名(形参列表)
    {
    	//方法体
    }
    
  • 例子
    static  void test(Colletion from, Collection to)
    

泛型的相关知识

泛型说明
  • 当创建带泛型声明的自定义类,为该类定义构造器时,构造其名还是原来的类名,不要增加泛型声明。
  • 不管“<>”中实际类型参数是什么,系统会默认他们是相同的类。
  • 不能在静态方法、静态初始化、静态变量的声明和初始化中使用泛型形参。
  • Java泛型的设计原则是:只要代码在编译时没有出现警告,就不会遇到运行时ClassCastException异常。
  • 如果在使用带泛型声明的类时不指定实际类型,默认是声明该泛型形参的第一个上限类型。
  • 当把一个具有泛型信息的对象赋给另一个没有泛型信息的变量时,它的类型信息会被删掉(变成泛型参数的上限)。
    -通配符/受限泛型
    通配符上限: //上限为T类,只允许类型为T类或T的子类。协变。
    通配符下限: //下限是T类,只允许类型为T类或T的父类。逆变。
  • 警告提示
    如果希望看到“使用了未经检查或不安全的操作”警告的更详细信息,可以使用javac命令增加-Xlint:unchecked实现。
泛型方法
  • 如果形参列表中有多个同类型的泛型形参,可以把该类型提取出来,单独写成泛型形参声明。
  • 泛型方法运行泛型形参被用来表示方法的一个或多个参数之间的类型依赖关系,或者方法返回值与参数之间的类型依赖关系。如果没有这样的类型依赖关系,就不应该使用泛型方法。
  • 语法
    //T和S为不同的泛型形参声明
    修饰符  返回值类型 方法名(形参列表)
    {
    	//方法体
    }
    
  • 例子
    static  void test(Colletion from, Collection to)
    
泛型数组
  • 允许使用:new ArrayList[10];
  • 不允许使用:new ArrayList[10];

Lambda表达式

Lambda表达式简介

Lambda表达式允许使用更简洁的代码来创建只有一个抽象方法(函数式接口)的接口的实例。

  • 作用:便捷的创建函数式接口的的实例。
  • 由三部分组成
    1. 形参列表(如果只有一个形参,可以省略括号)
    2. 箭头(->)
    3. 代码块:如果只有一条语句,可以省略花括号。如果只有一条return,可以省略return关键字。

Lambda表达式案例

例子1
//Runnable接口中只包含一个无参数的方法
//Lambda表达式代表的匿名方法实现了Runnable接口中唯一的、无参数的方法
//因此下面的Lambda表达式创建了一个Runnable对象
Runnable r = () ->{
  for(int i = 0;i<100;i++){
      System.out.println();
  }
};
例子2
//把int[] target的值传递到代码块中
(int[] target)->{
    int sum=0;
    for(int tmp:target){
        sum += tmp;
    }
    System.out.println("数组元素的总和是:"+sum);
}
引用类方法
```
//以下两个方法相同
Converter con1 = from -> Integer.valueOf(from);  //与下面的相同
Converter con1 = Integer::valueOf;  
//调用Integer类的valueOf()类方法实现Converter函数式接口中的唯一抽象方法。调用参数将会直接传给Integer类的valueOf()类方法。
```
对象实例方法
```
//以下两个方法相同
Converter con1 = from -> "fkit.org".valueOf(from);  //与下面的相同
Converter con1 = "fkit.org"::valueOf;  
//调用"fkit.org"的valueOf()实例方法实现Converter函数式接口中的唯一抽象方法。调用参数将会直接传给"fkit.org"对象的valueOf()类方法
```
引用构造器
```
//以下两个方法相同
YourTest yt = (String a) -> new JFrame(a);  //与下面相同
YourTest yt = JFrame::new;  //调用某个JFrame类的构造器来实现YourTest函数式接口中唯一的抽象方法。
JFrame jf = yt.win("我的应用");  //应用方法
```

Lambda表达式相关知识

  • Lambda表达式的类型,被称为“目标类型(targe type)”,Lambda表达式的目标类型必须是“函数式接口(functional interface)”。函数是接口代表只包含一个抽象方法的接口。
  • 是Java 8的重要更新。
  • 典型的4类函数式接口
    • XxxFunction:这类接口通常包含apply()抽象方法,该方法对参数进行处理、转换,返回新值。
    • XxxConsumer:这类接口通常包含accept()抽象方法,和apply()类型
    • XxxxPredicate:这类接口通常包含test()抽象方法,通常用来对参数进行某种判断
    • XxxSupplier:这类接口通常包含getAsXxx()抽象方法,会按照某种逻辑算法返回一个数据。
  • Lambda表达式与匿名内部类主要的区别
    • 匿名内部类实现的抽象方法的方法体允许调用接口中定义的默认方法;但Lambda表达式的代码块不允许调用接口中定义的默认方法。
  • Lambda表达式支持的方法引用和构造器引用。如果Lambda表达式的代码块只有一条代码,则可以在代码块中使用方法引用和构造器引用(既更加简写)。
    种类 示例 说明 对应的Lambda表达式
    引用类方法 类名::方法 函数式接口中被实现方法的全部参数传给该类方法作为参数 (a,b,…)-> 类名.类方法(a,b,…)
    引用特定对象的实例方法 特定对象::实例方法 函数式接口中被实现方法的全部参数传给该方法作为参数 (a,b,…)-> 特定对象.实例方法(a,b,…)
    引用某类对象的实例方法 类名::实例方法 函数式接口中被实现方法的第一个参数作为调用者,后面的参数全部传给该方法作为参数 (a,b,…)-> a.实例方法(b,…)
    引用构造器 类名::new 函数式接口中被实现方法的全部参数传给该构造器作为参数 (a,b,…)-> new 类名(a,b,…)

其他

参考资料

  • 《疯狂Java讲义(第4版)》 李刚

你可能感兴趣的:(Java基础)