Java泛型與Kotlin高階函數(shù)及語法糖

  • java泛型

    1. 什么是泛型? 泛指一切類型

      常使用 T R V K I O 表示

    2. 協(xié)變與形變

      class MyClass {
          public static void main(String[] args) {
              List<Object> a = new ArrayList();
              List<String> b = new ArrayList();
              a = b; // 報(bào)錯(cuò),為什么,a 需要 List<Objects>類型,而b 為List<String>類型
              *****************
              // 此時(shí)需要使用協(xié)變
              父類接收子類 協(xié)變 ? extends 
              List<? extends Object> c = new ArrayList(); // ? 為占位符,表示一個(gè)繼承于Object的子類
              List<String> d = new ArrayList();
              c = d;// 正確!!!
              *****************
              List<Object> e = new ArrayList();
              List<String> f = new ArrayList();
              f = e;// 報(bào)錯(cuò),f需要List<Object>類型,而e為List<String>類型,類型不匹配
              *****************
              // 此時(shí)需要使用形變
              子類接收父類 形變 ? super
              List<Object> g = new ArrayList();
              List<? super String> h = new ArrayList();
              h = g;// 正確!
          }
      }
      
    3. java泛型類的使用

      注意:泛型類中的方法只是使用了泛型類類型作為參數(shù)的函數(shù),不是泛型函數(shù)

      // 泛型類
      // T type
      class Bag<T> {
          private T value;
          public void setValue(T value) {
              this.value = value;
          }
          public T getValue {
              return this.value;
          }
          // main
          public static void main(String[] args) {
              // 前面<> 和 后面<> 必須指定一處類型
              Bag<String> schoolBag = new Bag<>();
              schoolBag.setValue("語文書");
              System.out.println(schoolBag.getValue());
          }
      }
      
  • kotlin泛型類的使用

    1. kotlin泛型類的使用

      kotlin: out 這個(gè)類型只能作為返回值 輸出 生產(chǎn)

      kotln: in只能作為參數(shù) 接受 消費(fèi)

      class Bag<in I,out O>(var value: @UnsafeVariance I,var result: @UnsafeVariance O) {
          fun setValue(v1: I) {
              value = v1
          }
          fun getValue(): O {
              return result
          }
      }
      
  • Kotlin泛型函數(shù)的使用

    何為泛型函數(shù)?不確定參數(shù)或者返回值類型的函數(shù)就是泛型函數(shù)

    1. 僅有一個(gè)泛型

      fun <T> test() {}
      fun <T> test1(): T {}
      fun <T> test2(v1: T) {}
      
    2. 放回值和參數(shù)類型均需要自己指定

      fun <T,R> test(v1: T, v2: T): R? {
          return null
      }
      
  • Kotlin高階函數(shù)分析

    1. 何為高階函數(shù)與為什么需要使用inline?

      高階函數(shù)是將函數(shù)用作參數(shù)或返回值的函數(shù),實(shí)際開發(fā)過程中一般所有高階函數(shù)都必須使用inline修飾,使之成為內(nèi)聯(lián)函數(shù)。不使用inline修飾高階函數(shù)時(shí),使用此類高階函數(shù)會(huì)帶來一些運(yùn)行時(shí)的效率損失,因?yàn)榫幾g時(shí),每一個(gè)函數(shù)都是一個(gè)對(duì)象,內(nèi)存分配(對(duì)于函數(shù)對(duì)象和類)和虛擬調(diào)用會(huì)引入運(yùn)行時(shí)間開銷降低效率。當(dāng)inline修飾了高階函數(shù)時(shí),此時(shí)編譯時(shí)程序只是做了一個(gè)展開/替換(類似于C語言的宏定義),所以在許多情況下我們通過使用inline內(nèi)聯(lián)化 lambda 表達(dá)式來消除這類的開銷。

    2. lambda表達(dá)式分析

      inline fun String.show1(lambda: (String) -> Unit) {
          // lamba表達(dá)式為String類型的形參,沒有返回值
          // lambda 表達(dá)式里面是 it
          lambda(this)
      }
      inline fun String.show2(lambda: String.() -> Unit ) {
          // lambda 表達(dá)式里面是 this
          this.lambda()
      }
      fun main() {
          "jack".show1{
              println("hello $it")
          }
          "Merry".show2{
              println("hello $this")
          }
      }
      
    3. lambda與泛型的綜合運(yùn)用

      • 給任意一個(gè)類型添加一個(gè)擴(kuò)展函數(shù),lambda中使用it訪問這個(gè)對(duì)象
      fun <T> T.show1(lambda: (T) -> Unit) {
          lambda(this) // 在這個(gè)函數(shù)中this指代的是調(diào)用這個(gè)擴(kuò)展函數(shù)類型為T的對(duì)象,并把它作為參數(shù)傳遞給lambda,
                     //  在lambda中使用it訪問這個(gè)對(duì)象
      }
      
      • 給任意一個(gè)類型添加一個(gè)擴(kuò)展函數(shù),lambda中使用this訪問這個(gè)對(duì)象
      fun <T> T.show2(lambda: T.() -> Unit) {
          this.lambda() // this指代是調(diào)用這個(gè)擴(kuò)展函數(shù)類型為T的對(duì)象,再將其作為調(diào)用lambda的對(duì)象
                      // 在lambda中使用this訪問這個(gè)對(duì)象
      }  
      
      • 給任意一個(gè)類型添加一個(gè)擴(kuò)展函數(shù),并將這個(gè)對(duì)象傳遞給lambda表達(dá)式,lambda返回值的類型由lambda最后一行的結(jié)果決定
      fun <T,R> T.show3(lambda: (T) -> R) {
         val result = lambda(this)
         println(result!!::class.java.name)
         // 上行可以打印出lambda表達(dá)式最后一行結(jié)果的值
      }
      
    • 運(yùn)行效果如下


      屏幕截圖 2022-05-29 172914.png
      屏幕截圖 2022-05-29 173046.png
  • Kotlin語法糖分析

    • apply分析

      apply作用:使用apply可以進(jìn)行初始化操作

      inline fun <T> T.myApply(lambda: T.() -> T): T {
          this.lambda()
          return this
      }
      
    • also分析

      also作用:使用also可以完成同時(shí)性的操作

      inline fun <T> T.myAlso(lambda: (T) -> T): T {
          lambda(this)
          return this
      }
      
    • run分析

      run作用:使用run可以執(zhí)行一段代碼

      inline fun <R> myRun(lambda: () -> R): R {
         return lambda()
      }
      inline fun <T,R> T.myRun(lambda: T.() -> R): R {
         return this.lambda()
      }
      
    • with分析

      inline fun <T,R> myWith(value: T,lambda: T.() -> R): R {
          return value.lambda()
      }
      
    • forEach分析

      forEach作用:使用forEach可以遍歷完成相關(guān)的操作

      inline fun <T> Iterable<T>.myForEach(lambda: (T) -> Unit): Unit {
         for (item in this) {
             lambda(item)
         }
      }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容