2015-08-29 23 views
6
public interface MyFunc<T> { 

    boolean func(T v1, T v2); 

} 
public class HighTemp { 

    private int hTemp; 

    HighTemp(){ 

    } 
    public HighTemp(int ht) { 
     this.hTemp = ht; 
    } 

    boolean sameTemp(HighTemp ht2){ 
     return hTemp == ht2.hTemp; 
    } 

    boolean lessThanTemp(HighTemp ht2){ 
     return hTemp < ht2.hTemp; 
    } 
} 
class InstMethWithObjRef { 

    static <T> int counter(T[] vals, MyFunc<T> f, T v){ 
     int count = 0; 

     for (int i = 0; i < vals.length; i++) { 
      if(f.func(vals[i], v)) count++; 
     } 
     return count; 
    } 
    public static void main(String[] args) { 
     int count; 
     //Create an array of HighTemp objects. 
     HighTemp[] weekDayHighs = {new HighTemp(89), new HighTemp(82), 
            new HighTemp(90), new HighTemp(89), 
            new HighTemp(89), new HighTemp(91), 
            new HighTemp(84), new HighTemp(83)}; 
     count = counter(weekDayHighs, HighTemp::lessThanTemp,new HighTemp(89));  
     System.out.println(count);   
    } 
} 

Xin giải thích như thế nàoHãy Giải thích Java 8 Phương pháp tham khảo để dụ Phương pháp sử dụng tên lớp

  1. boolean sameTemp() tương thích với func() trong giao diện chức năng.
  2. sameTemp() phương pháp đã được triển khai trên func() trong Giao diện chức năng.
  3. count = counter(weekDayHighs, HighTemp::sameTemp, new HighTemp(89)); đang làm việc

Hãy Giải thích Tất cả các điểm riêng biệt.

+0

Mã này hoạt động f ine nhưng tôi không hiểu làm thế nào sameTemp() là tương thích với func(), khi func() có hai tham số và sameTemp() có một. –

+0

bình luận cho tôi nếu bạn không hiểu câu hỏi của tôi –

+0

Bạn có chắc chắn mã này hoạt động không? 'hTemp' được khai báo là' static' nên mỗi khi bạn xây dựng 'HighTemp' giá trị thay đổi cho tất cả các cá thể, điều này sẽ dẫn đến' count' là luôn luôn 0. – MirMasej

Trả lời

4

tương đương biểu lambda của HighTemp::lessThanTemp

(highTemp1, highTemp2) -> { 
    return highTemp1.lessThanTemp(highTemp2); 
} 

Đây là một trong những tính năng của Java8 tên Reference to an Instance Method of an Arbitrary Object of a Particular Type


Hãy xem xét ví dụ sau,

interface FIface<T> { 
    int testMethod(T a, T b); 
} 

class Test2 { 

    private String str; 

    Test2(String str) { 
     this.str = str; 
    } 

    int ok(Test2 test2) { 
     System.out.println("Currnet String : "+ this.str);//Refer to t1 
     System.out.println("Test String : "+test2.str);//Refer to t2 
     return 0; 
    } 

} 

public class Test { 

    public static <T> int checkCall(T t1, T t2, FIface<T> fiFace) { 
     //Here Test2 :: ok is equivalent to t1.ok(t2) 
     return fiFace.testMethod(t1, t2); 
    } 

    public static void main(String[] args) { 
     checkCall(new Test2("a"), new Test2("b"), Test2 :: ok); 
    } 

} 

OUTPUT

Currnet String : a 
Test String : b 

Lưu ý ở đây rằng Test2 :: ok có giá trị trong cuộc gọi thậm chí ok phương pháp không phải là tĩnh.

Khi bạn gọi phương thức checkCall cho giao diện chức năng bạn vẫn còn có hai đối số là t1t2 và cho rằng biểu thức lambda hợp lệ có thể có các thông số như (Test t1, Test t2) vì vậy phương pháp của bạn Test2 :: ok đây trở nên có giá trị cho cuộc gọi. Nội bộ nó hoạt động theo cách này t1.ok(t2).

Vì vậy, fiFace.testMethod(t1, t2); sẽ sẽ gọi phương thức như t1.ok(t2)

+0

Thưa bạn, bạn có thể giải thích cho tôi một ví dụ về việc sử dụng chữ ký phụ trong một chương trình nhỏ tương tự như chương trình của tôi không. Để tôi có thể dễ dàng hiểu, Cảm ơn –

+0

Thêm nhận xét trong chương trình để giải thích. Thế thì tuyệt quá. –

1

Đối với người mới bắt đầu tôi không phải là một lập trình viên chuyên nghiệp. Tôi cũng đã có một khó khăn lớn trong việc hiểu được cái gọi là "Tham chiếu đến một phương pháp thể hiện đối tượng tùy ý của một loại đặc biệt" Tôi nghĩ điều này có thể hữu ích cho ai đó đến đây từ tìm kiếm trên google.
Tôi hiểu nó một chút với sự trợ giúp của các biểu thức lambda.

Trong mã của bạn HighTemp::lessThanTemp dưới dạng biểu thức Lambda sẽ giống như (x,y)->{x.lessThanTemp(y);} Thay thế tham chiếu phương thức bằng biểu thức lambda này sẽ tạo ra cùng một kết quả. Biểu thức Lambda ở trên hoặc tham chiếu phương thức đều cho biết phương thức giao diện cần làm.
Khi bạn sử dụng tham chiếu phương thức, nó sẽ cho phương thức giao diện sử dụng phương thức được gọi từ lớp đã cho, để thực hiện chức năng của nó.Do đó, nếu bạn chuyển đổi HighTemp::lessThanTemp thành từ tiếng Anh, có vẻ như "triển khai phương thức lessThanTemp là lớp HighTemp khi triển khai chức năng giao diện". Như bạn có thể đã nhận thấy trong trường hợp đó các kiểu trả về và các kiểu đối số nên tương thích. Nếu không, bạn không thể thực hiện một giao diện.

Tôi sẽ cung cấp cho bạn một mã ví dụ đơn giản khác. Các ví dụ khác giúp hiểu khái niệm này.

interface myint{ 
    int returnit(Test t ,int y); 
} 
class Test{ 
    int x=0; 
    public Test(int x){ 
     this.x=x; 
    } 

    public int addNumbers(int y){ 
     return x+y; 
    } 
    public int subtractNumbers(int y){ 
     return x-y; 
    } 

} 

public class myclass{ 
    private static void myMethod(Test t,myint inf,int y){ 
     int x=inf.returnit(t, y); 
     System.out.println(x+""); 
    } 
    public static void main(String[] args){ 
     myMethod(new Test(4),Test::addNumbers,7); 
     myMethod(new Test(4),Test::subtractNumbers,7); 
    } 
} 


Output sẽ là:

11 
-3 


Đây là cách đơn giản nhất tôi có thể tưởng tượng nó. Xem cách các kiểu trả về và các kiểu đối số được đối sánh bằng cách sử dụng mẫu câu trên. Hãy dành chút thời gian cho nó.

0

Đây là giao diện

package learninglambdaexp; 

@FunctionalInterface 
public interface TempInterface { 

    public boolean validTemp(Temperature temp); 
} 

Đây là lớp

package learninglambdaexp; 

public class Temperature { 

    private int temp; 

    public Temperature(int temp) { 
     this.temp = temp; 
    } 

    public boolean isEvenTemp() { 
     return temp % 2 == 0; 
    } 

    public boolean isOddTemp(){ 
    return !isEvenTemp(); 
    } 
} 

Đây là lớp với Phương pháp chính

package learninglambdaexp; 

import java.util.ArrayList; 
import java.util.List; 

public class AnotherMainClass { 

    public static void main(String[] args) { 

     List<Temperature> tempCollection = new ArrayList<>(); 
     tempCollection.add(new Temperature(100)); 
     tempCollection.add(new Temperature(20)); 
     tempCollection.add(new Temperature(30)); 
     tempCollection.add(new Temperature(40)); 
     tempCollection.add(new Temperature(50)); 
     tempCollection.add(new Temperature(60)); 
     tempCollection.add(new Temperature(70)); 
     int k1 = countVariation(tempCollection, Temperature::isEvenTemp); 
     //int k2 = countVariation(Temperature::lowTemp); 
     System.out.println(k1); 
     // System.out.println(k2); 
    } 

    private static int countVariation(List<Temperature> tempCollection, TempInterface ti) { 
     int count = 0; 
     for (Temperature eachTemp : tempCollection) { 
      if (ti.validTemp(eachTemp)) { // (eachTemp) -> {return eachTemp.isEvenTemp();}; 
       count++; 
      } 
     } 
     return count; 
    } 
} 

Với một đối số của nó dễ dàng hơn để hiểu

Các vấn đề liên quan