1. 程式人生 > >java8新特性(方法引用、構造器引用)

java8新特性(方法引用、構造器引用)

前言:

接上一篇文章:Java8新特性(內建的核心函式式介面)http://blog.csdn.net/xinghuo0007/article/details/78603908

我們知道使用了Lambda表示式以後能夠是我們的程式碼的精簡,而且可讀性更強,但是有時Lambda表示式的Lambda體內的功能我們已經實現過了,
這個時候就可以使用我們的函式引用、構造器引用了

知識點一:方法引用

什麼是方法引用?

 答:方法引用是對Lambda表示式符合某種情況下的一種縮寫,使得我們的Lambda表示式更加的精簡,
 也可以理解為Lambda表示式的另一種表現形式(縮寫)

什麼時候使用方法引用呢?

答:當要傳遞給Lambda體內的操作,已經有實現的方法了,就可以使用方法引用了

方法引用使用的前提條件是什麼呢?

答:
    1.方法引用所引用的方法的引數列表必須要和函式式介面中抽象方法的引數列表相同(完全一致)

    2.方法引用所引用的方法的的返回值必須要和函式式介面中抽象方法的返回值相同(完全一致)

方法引用有什麼語法格式嗎?

方法引用一般有三種格式:

    1. 例項物件名::例項方法名
    2. 類名::靜態方法名
    3. 類名::例項方法名              (注意區別23的區別,下面會說)

23的區別:
    若Lambda 的引數列表的第一個引數,是例項方法的呼叫者,第二個引數(或無參)是例項方法的引數時,格式: 類名::
例項方法名

方法引用舉例:

舉例一:1. 例項物件名::例項方法名(案例一)
        Student student = new Student("XiangYang",23);
        Supplier<String> supplier = ()->student.getName();
        System.out.println("Lambda形式: "+supplier.get());


        Supplier<String> supplier1 = student :: getName;
        System.out
.println("方法引用形式: "+supplier1.get()); class Student{ private String name; private int age; public Student(String name, int age) { this.name = name; this.age = age; } public Student(String name) { this.name = name; } public Student(int age) { this.age = age; } public Student() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
舉例一: 1. 例項物件名::例項方法名 (案例二)
   @org.junit.Test
    public void test6(){
        //傳統Lambda表示式
        Consumer<String> consumer = (x) -> System.out.println(x);
        consumer.accept("Hi: 我是Lambda表示式實現的!"); //列印:Hi: 我是Lambda表示式實現的!
        //方法引用實現
        consumer = System.out::println;
        consumer.accept("Hello : XiangYang,我是使用方法引用實現的 ");//列印:Hello : XiangYang,我是使用方法引用實現的 
    }
舉例二: 2. 類名::靜態方法名
 public class Test{
     @org.junit.Test
    public void test8(){
        //傳統Lambda表示式
        Consumer<String> consumer = (str) -> sop(str);
        consumer.accept("Hello : XiangYang"); //列印:Hello : XiangYang

        //方法引用方式
        consumer = Test::sop;
        consumer.accept("Hello : XiangYang"); //列印:Hello : XiangYang
    }
}
舉例三: 3. 類名::例項方法名
    @org.junit.Test
    public void test7(){
        //傳統Lambda表示式
        BiPredicate<String,String> biPredicate = (x,y) -> x.equals(y);
        boolean test = biPredicate.test("hello", "hi");
        System.out.println(test);//false

        //方法引用
        biPredicate = String::equals;
        test = biPredicate.test("hello", "hello");
        System.out.println(test);//true

    }

注意:

1.這裡一定要知道 類名::例項方法名  這種語法的使用條件:
  說明:a,b是所有方法引用的必要條件,c是使用 類名::例項方法名的特殊前提

    a.方法引用所引用的方法的引數列表必須要和函式式介面中抽象方法的引數列表相同(完全一致)

    b.方法引用所引用的方法的的返回值必須要和函式式介面中抽象方法的返回值相同(完全一致)

    c.若Lambda 的引數列表的第一個引數,是例項方法的呼叫者,第二個引數(或無參)是例項方法的引數時,格式: 類名::例項方法名 

2.解釋一下:
    首先看一下使用傳統Lambda表示式的形式:
        //傳統Lambda表示式
        BiPredicate<String,String> biPredicate = (x,y) -> x.equals(y);
        boolean test = biPredicate.test("hello", "hi");
        System.out.println(test);//false

    注意看: equals方法的呼叫者是x,equals方法引數是y,這符合我們上面的c條件;所以能使用

方法引用總結:

1.一定弄明白使用方法引用的前提條件(2個)

    a. 方法引用所引用的方法的引數列表必須要和函式式介面中抽象方法的引數列表相同(完全一致)

    b .方法引用所引用的方法的的返回值必須要和函式式介面中抽象方法的返回值相同(完全一致)

  這裡使用程式碼解釋一下:

    @org.junit.Test
    public void test6(){
        //傳統Lambda表示式
        Consumer<String> consumer = (x) -> System.out.println(x);
        consumer.accept("Hi: 我是Lambda表示式實現的!"); //列印:Hi: 我是Lambda表示式實現的!
        //方法引用實現
        consumer = System.out::println;
        consumer.accept("Hello : XiangYang,我是使用方法引用實現的 ");//列印:Hello : XiangYang,我是使用方法引用實現的 
    }

解釋:
    1.首先我們看一下Consumer的函式式介面的原始碼的介面
        void accept(T t);
     由於我們給泛型傳入的是String型別
          Consumer<String> consumer = (x) -> System.out.println(x);
     所以此時

      //這是函式式介面中抽象方法,接收了實際型別String,沒有返回值
       void accept(T t); ==》 void accept(String t); 
    2 我們在看我們的Lambda體內的實現      
         System.out.println(x);
      此時,我們檢視println方法的原始碼:

    //這是 方法引用所引用的方法 的引數型別是String,無返回值
    public void println(String x) {
        synchronized (this) {
            print(x);
            newLine();
        }
    }

  3. 此時函式式的介面中的引數型別與返回值 和   方法引用所引用方法的引數型別與返回值相同,所以可以使用方法引用,型別為: 例項物件名:: 例項方法名 

知識點二:構造器引用

什麼是構造器引用?

答:與函式式介面相結合,自動與函式式介面中方法相容。
可以把構造器引用賦值給定義的方法。 

什麼時候用構造器引用?

答:在使用Lambda表達的時,滿足使用構造器引用條件的時候可以使用

構造器使用的前提是什麼?

答:構造器引數列表要與介面中抽象方法的引數列表一致!

構造器引用的語法格式是什麼?

語法格式:
    類名 :: new 

舉例:

說明:Student類見方法引用舉例一的案例

  @org.junit.Test
    public void  test9(){

        //傳統Lambda方式
        Supplier<Student> studentSupplier = ()-> new Student();
        Student student = studentSupplier.get();
        System.out.println(student);//Student{name='null', age=0}

        //構造器引用
        studentSupplier = Student::new;
        student = studentSupplier.get();
        System.out.println(student);//Student{name='null', age=0}
    }

案例說明:

1.首先我們要只是Supplier介面的抽象方法定義為:
       T get();
    我們程式碼
        Supplier<Student>此時已經泛型T傳入Student型別
    相當於:
      Student get(); //函式式介面中是無參,返回值為Student
2.在看我們的Student類的定義中一個無參構成器
     Student(){} //構造器無參,返回Student型別(嚴格意義上兩個構成函式沒有返回值,我們先這樣理解)

3.此時,符合我們使用構造方法引用的前提:
        構造器引數列表要與介面中抽象方法的引數列表一致!
  所以:可以使用構造引用。          

知識點三:陣列引用

 說明: 
     這裡單獨把陣列引用拿出來實際上是強調一下,陣列引用和構造引用基本相同,直接上一個案例來說明問題

案例:

 @org.junit.Test
    public void test10(){
        //需求:獲取n個int[] 陣列

        //傳統Lambda實現
        Function<Integer,int[]> function = (i) -> new int[i];
        int[] apply = function.apply(5);
        System.out.println(apply.length); // 5

        //陣列型別引用實現
        function = int[] ::new;
        apply = function.apply(10);
        System.out.println(apply.length); // 10
    }

相關推薦

Java8特性方法引用構造引用陣列引用

目錄: 1、方法引用 1.1、物件 :: 例項方法 1.2、類 :: 靜態方法 1.3、類 ::例項方法 2、構造器引用 2.1、介紹 2.2、使用 3、陣列引用 3.1、介紹 3.2、使用 1、方法引用 若lambda體中的內容有方法已經實現了,

java8特性方法引用構造引用

前言: 接上一篇文章:Java8新特性(內建的核心函式式介面)http://blog.csdn.net/xinghuo0007/article/details/78603908 我們知道使用了L

JDK8 引用方法引用構造引用陣列引用

/** * @Description: * 一、方法引用 * 如果lambda 體中的內容有方法已經實現了,我們可以使用“方法引用” * (可以理解為方法引用是 Lambda表示式的另外一種表現形式) * 主要有三種語法格式: * 物件 ::例項方法名 * 類:: 靜

java8 特性方法引用::

java8中的方法引用(雙冒號)::是類似於C++的域運算子,獲取方法使用的。 使用場景:cars.forEach( Car::repair ); 1、構造方法引用(Class::new):       相當於建立物件;如果函式式介面方法有引數,會匹配具體有

JAVA8特性方法引用構造引用

一:簡介        1:什麼是方法引用?                    若Lambda體中的功能,已經有方法提供了實現,可以使用方法引用。                    可以將方法引用理解為Lambda表示式的另一種表現形式。        2:方法

Java8特性方法引用

方法引用 方法引用其實就是Lambda表示式的簡寫,標誌是 :: 1、和Lambda表示式比較 public class Java8Test { public s

java8特性 λstream 與 預設介面方法

1.lambda λ表示式本質上是一個匿名方法,用來方便地實現函式介面。也就是說,λ表示式主要用於替換以前廣泛使用的內部匿名類。  讓我們來看下面這個例子:     public int add(int x, int y) {         return x + y;  

2020了你還不會Java8特性方法引用詳解及Stream 流介紹和操作方式詳解

方法引用詳解 方法引用: method reference 方法引用實際上是Lambda表示式的一種語法糖 我們可以將方法引用看作是一個「函式指標」,function pointer 方法引用共分為4類: 類名::靜態方法名 引用名(物件名)::例項方法名 類名::例項方法名 (比較不好理解,個地方呼叫的方

JAVA8特性(三)——方法引用

我們之前寫Lambda表示式,如果Lambda表示式有對應方法,我們可以直接引用方法作為Lambda表示式。這種做法叫做方法引用。方法引用用”::”分隔。 例子 @Test public void methodRefTest() { MethodReference.

Java8特性------介面中可以定義方法

 Java8比起以前的版本存在很大的變化,我們知道在之前的版本中介面只能是定義抽象的方法,是不能定義實現的,但是在java8環境下,這個不可能已經變得可能。下面我們通過例子一步一步的來講解下java8

JDK8特性04 方法引用構造引用

def 形式 com 理解 nts hello 數列 getname println import java.io.PrintStream; import java.util.Comparator; import java.util.function.*; /**

java8方法引用構造引用

<1.方法引用>若lambda體中的內容有其他方法已經實現了,可以使用“方法引用”(可以理解為方法體引用是lambda表示式的另外一種體現)      主要有三種語法格式:         

Java 8 特性———方法引用構造引用

1.方法引用 當要傳遞給Lambda體的操作,已經有實現的方法了,可以使用方法引用!(實現抽象方法的引數列表,必須與方法引用方法的引數列表保持一致!)方法引用:使用操作符“::” 將方法名和物件或類的名字分隔開來。 如下三種主要使用情況: 物件::例項方法 類::靜態方

Java8特性lambdaStreamOptional

1、λ表示式lambda表示式:λ表示式是Java8新增的一個特性,《Core Java》中的對它的解析是——“一個可傳遞的程式碼塊,可以在以後執行一次或多次”。從日常開發的角度來看,它可以簡化我們的很

Java8特性方法引用

# 一 前言 日常開發中,經常使用到Lambda表示式,例如: ```java public static void main(String[] args) { List list = Arrays.asList(1, 5, 10, 4, 2); // 列印列表中的每一個數字 li

Java8特性---Lambda表示式

Java8新特性之Lambda表示式 Lambda的語法格式 語法格式一:無引數,無返回值 語法格式二:有一個引數,並且無返回值 語法格式三:若只有一個引

java8特性簡述十大特性

截止稿前,java10都已經發布了,現在我們來討論一下java8(2014年3月釋出)。 本文的討論,只是一個簡述,更加具體的,各位可以參照各自的專題講解 說在前面 你真的開始用JDK8了嗎? 如果你沒有用上一些新特性,請別說自己使用了Java8。 Java 8可謂

java8第四課:方法引用構造引用

  這節課我們開始講方法引用和構造器引用,直接看程式碼   public class MethodReference {     /**      * 方法引用:一種lambda表示式的簡寫方

java8特性-預設方法

作為一個java程式猿,經常會被問基礎怎麼樣,對於這個問題,我理解的有兩方面:一是對於java基礎的理解和掌握,比如JDK的相關特性;二是工作的經歷,畢竟,語言程式設計是一門實戰性質的藝術,就算掌握了千萬理論,編寫不出實際的程式碼,等於扯淡。而且,隨著技術的革新,很多東西都不再是一成不變的,還記得剛出校門那會

Java8特性日期時間的API

1、新時間日期API java.time – 包含值物件的基礎包 java.time.chrono – 提供對不同的日曆系統的訪問 java.time.format – 格式化和解析時間和日期 java.time.temporal – 包括底層框架和擴