2013-08-23 31 views
9

Trong khi tôi đang cố gắng giải quyết tập thể dục from generics tutorial Q&A câu trả lời của tôi là hơi khác nhauLàm thế nào để viết một phương pháp chung để tìm phần tử tối đa và gọi phương thức đó?

Đáp My

public static <T extends Comparable<? super T>> 
    T max(List<? extends T> list, int begin, int end) //Option1 

public static <T extends Comparable<T>> 
    T max(List<? extends T> list, int begin, int end) //Option2 

từ câu trả lời trích dẫn dưới đây

Vì vậy, câu hỏi của tôi là

  • OPTION1 : Nó sẽ tạo ra bất kỳ sự khác biệt nào nếu T extends Object & Comparable<? super T> được thay thế bằng T extends Comparable<? super T>. Không phải là extends Object tiềm ẩn?

  • Option2: Có sự khác biệt nào nếu Comparable<? super T> được thay thế bằng Comparable<T>? nếu như vậy như thế nào?

  • Hoàn thành mã Eclipse tạo biến cục bộ List<? extends Comparable<? super Comparable<? super T>>> list; trên Ctrl + 1 max(list, 1, 10); dài một chút. Làm thế nào để xác định một lớp học (phân cấp) mở rộng Comparable<? super T>, tạo danh sách và thêm trường hợp vào danh sách và gọi phương thức dưới đây? Về cơ bản tôi muốn biết làm thế nào để gọi max() sau khi thêm trường lớp A or B vào một danh sách nơi class B extends A


Viết một phương pháp tổng quát để tìm các phần tử tối đa trong phạm vi [bắt đầu, kết thúc) của một danh sách.

Trả lời:

import java.util.*; 

public final class Algorithm { 
    public static <T extends Object & Comparable<? super T>> 
     T max(List<? extends T> list, int begin, int end) { 

     T maxElem = list.get(begin); 

     for (++begin; begin < end; ++begin) 
      if (maxElem.compareTo(list.get(begin)) < 0) 
       maxElem = list.get(begin); 
     return maxElem; 
    } 
} 
+2

Được trả lời một phần tại đây: http://stackoverflow.com/questions/10339338/t-extends-object-e-vs-t-extends-e –

+0

Tôi thực sự không hiểu câu hỏi thứ 3 của bạn. Bạn có thể xây dựng nó một chút không? –

+0

Đối với lời gọi phương thức nào thì eclipse tạo biến cục bộ đó? Tôi không hiểu tại sao nó lại làm như vậy. Ít nhất kiểu lồng nhau có thể so sánh được thực sự không hợp lý ở đây. –

Trả lời

8

Nó sẽ thực hiện bất kỳ sự khác biệt nếu Comparable<? super T> được thay thế bằng Comparable<T>? nếu như vậy như thế nào?

Hãy nhớ rằng so sánh áp luôn người tiêu dùng, ví dụ, một Comparable<T> tiêu thụ T trường hợp, vì vậy nó nên luôn luôn preferrable sử dụng Comparable<? super T> thay vì Comparable<T> (Trích dẫn - PECS). Nó sẽ tạo ra sự khác biệt trong trường hợp bạn đang so sánh một loại có siêu lớp thực hiện một Comparable<SuperType>. Xét đoạn mã sau:

class Parent implements Comparable<Parent> { 
    protected String name; 

    @Override 
    public int compareTo(Parent o) { 
     return this.name.compareTo(o.name); 
    } 
} 

class Child extends Parent { 
    public Child(String name) { 
     this.name = name; 
    } 
} 

Bây giờ nếu bạn cho tham số kiểu của bạn như T extends Comparable<T>, bạn sẽ không thể gọi là phương pháp cho List<Child>, như Child không thực hiện Comparable<Child> nhưng Comparable<Parent>:

public static <T extends Comparable<T>> T max(List<? extends T> list, int begin, int end) { 
    ... 
} 

public static void main(String[] args) { 
    List<Child> list = new ArrayList<Child>(); 
    max(list, 0, 2); // Error with current method. Child does not implement Comparable<Child> 
} 

Do đó, giới hạn thông số loại phải là T extends Comparable<? super T>.

Lưu ý rằng, bạn không thể thay đổi trẻ em của bạn lớp:

class Child extends Parent implements Comparable<Child> 

bởi vì trong trường hợp đó, Child lớp sẽ mở rộng từ instantiation khác nhau của cùng một loại chung chung, mà không được phép.


Nó sẽ thực hiện bất kỳ sự khác biệt nếu T extends Object & Comparable<? super T> được thay thế bằng T extends Comparable<? super T>. Không mở rộng tiềm ẩn đối tượng?

Vâng, có sự khác biệt giữa hai giới hạn. Trong giới hạn 1 st, việc xóa tham số kiểu là Object, trong khi trong giới hạn 2 thứ, việc xóa là Comparable.

Vì vậy, mà không bị ràng buộc Object, mã của bạn sẽ biên dịch để:

public static Comparable max(List list, int begin, int end) 

Vấn đề này có thể đến khi bạn đang generifying di sản phi mã chung. Đó là cần thiết để cung cấp cho Object cũng như ràng buộc trên để tránh phá vỡ khả năng tương thích mã Byte. Bạn có thể đọc thêm về nó trên liên kết này: Angelika Langer - Programming Idioms

+0

Việc xóa một phương thức chỉ tạo ra sự khác biệt cho các kiểu tham số đầu vào, không phải kiểu trả về, và ràng buộc 'Object' không tạo ra sự khác biệt ở đó: nó vẫn' max (List, int, int) '. 'Object' thực sự là không cần thiết ở đây. –

+0

@LouisWasserman. Vâng, trên cái nhìn đầu tiên tôi cũng nghĩ như vậy, sau đó tôi đọc trên liên kết mà tôi đã thêm vào cuối. Nó nói rằng nó là cần thiết để duy trì khả năng tương thích mã byte. –

+0

@RohitJain Trong thực tế 'max (danh sách, 0, 2);' sẽ biên dịch tốt. nhưng 'Child child = max (danh sách, 0, 2);' sẽ không biên dịch. – Kachna

0

Có vẻ như có nhiều ký tự đại diện hơn mức cần thiết. Tôi có lẽ sẽ đi với

public static <T extends Comparable<? super T>> 
    T max(List<T> list, int begin, int end) 

Một phiên bản thậm chí nhiều hạn chế:

public static <T extends C, C extends Comparable<C>> 
    T max(List<T> list, int begin, int end) 

ví dụ T phải có một loại siêu đó là so sánh với bản thân . Ví dụ: T không được là Foo

class Foo implements Comparable<Object> 

Foo không có ý nghĩa; một so sánh chỉ có thể được so sánh một cách có ý nghĩa với loại riêng của nó. Điều khoản C extends Comparable<C> thừa nhận thực tế đó.

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