2008-10-09 32 views
15

Tuyên bố sau đây xác định cấu trúc dữ liệu nào?Java Generics Cú pháp cho mảng

List<ArrayList>[] myArray; 

Tôi nghĩ rằng nó nên khai báo một mảng mà mỗi phần tử là một List (ví dụ, một LinkedList hoặc một ArrayList) và yêu cầu rằng mỗi List chứa ArrayList đối tượng.

lập luận của tôi:

List<String> someList;    // A List of String objects 
List<ArrayList> someList;   // A List of ArrayList objects 
List<ArrayList>[] someListArray; // An array of List of ArrayList objects 

Sau khi chạy một số xét nghiệm, tôi xác định rằng nó chấp nhận một mảng mà mỗi phần tử là một đối tượng LinkedList và không xác định những gì các đối tượng LinkedList chứa.

Vì vậy, List<ArrayList> chỉ định những gì List phải chứa, nhưng List<ArrayList>[] chỉ định cách thực hiện List.

Tôi có thiếu gì đó không?

Đây là các thử nghiệm của tôi.

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


public class Generics1 { 

    public static void main(String[] args) { 

     List<ArrayList>[] someListArray; 

     someListArray = getArrayWhereEachElementIsAnArrayListObject(); 
     // Why does this satisfy the declaration? 
     //someListArray[0] => ArrayList object holding Strings 

     someListArray= getArrayWhereEachElementIsAListOfArrayListObjects(); 
     //someListArray[0] => ArrayList object holding ArrayList objects 

    } 

    public static List[] getArrayWhereEachElementIsAnArrayListObject() { 
     List[] arrayOfLists = new ArrayList[2]; 
     arrayOfLists[0] = getStringList(); 
     arrayOfLists[1] = getIntegerList(); 
     return arrayOfLists; 
    } 

    public static List[] getArrayWhereEachElementIsAListOfArrayListObjects() { 

     List list1 = new ArrayList(); 
     list1.add(getArrayList()); 

     List list2 = new ArrayList(); 
     list2.add(getArrayList()); 

     List[] arrayOfListsOfArrayLists = new ArrayList[2]; 
     arrayOfListsOfArrayLists[0] = list1; 
     arrayOfListsOfArrayLists[1] = list2; 
     return arrayOfListsOfArrayLists; 
    } 

    public static List getStringList() { 
     List stringList= new ArrayList(); 
     stringList.add("one"); 
     stringList.add("two"); 
     return stringList; 
    } 


    public static List getIntegerList() { 
     List intList= new ArrayList(); 
     intList.add(new Integer(1)); 
     intList.add(new Integer(2)); 
     return intList; 
    } 

    public static ArrayList getArrayList() { 
     ArrayList arrayList = new ArrayList() ; 
     return arrayList; 
    } 
} 
+0

Mỗi phần tử có thể được gán là myArray [0] = new ArrayList (); –

+0

Dường như tất cả các đối số kiểu chung đã bị tước khỏi mẫu mã của bạn. Điều này có thể xảy ra vì bạn đã đính kèm nó trong thẻ PRE và trang web giải thích các đối số loại là thẻ HTML không đúng định dạng hoặc bị cấm (theo Q31657). Bạn sẽ có thể chỉnh sửa nó. –

Trả lời

8

Ông Josh Bloch nói:

"thích danh sách này để mảng vì mảng là hiệp biến và Generics bất biến'

Bạn có lẽ có thể làm:

List<List<ArrayList>> someListArray; 

Điều này có thể cung cấp cho một số pe rformance hit (thậm chí không đáng chú ý tôi đặt cược) nhưng bạn sẽ nhận được an toàn loại tốt hơn tại thời gian biên dịch.

nhưng tôi nghĩ rằng câu hỏi nên được nhiều hơn xung quanh "tại sao" bạn cần điều này?

+0

Tôi không "cần" điều này. Tôi chạy qua tờ khai trong khi bảo trì mã và cố gắng hiểu ý nghĩa của lời tuyên bố. – user19685

+0

Ok thats mát mẻ, tôi chỉ kiểm tra ... – Mark

5
List<ArrayList>[] someListArray; 

mang đến cho bạn một:

array of (List of ArrayList) 

Nhưng do những hạn chế trong Java Generics (bug 6229728), bạn chỉ có thể thực sự tạo:

array of List 

và đúc nó:

List<ArrayList>[] someListArray = (List<ArrayList>[]) new List[5]; 
0

Bạn là đồng rrect nói:

Sau khi chạy một số kiểm tra, tôi xác định khai báo có nghĩa là mảng trong đó mỗi phần tử là đối tượng ArrayList.

Thực thi mã này

List<ArrayList>[] myArray = new ArrayList[2]; 

myArray[0] = new ArrayList<String>(); 
myArray[0].add("test 1"); 

myArray[1] = new ArrayList<String>(); 
myArray[1].add("test 2"); 

print myArray; 

Tạo kết quả này:

{["test 1"], ["test 2"]} 

Dường như với tôi không có lý do để không làm điều này thay vì:

List<ArrayList> myArray = new ArrayList<ArrayList>(); 
0

Danh sách là một Danh sách có khả năng giữ các đối tượng ArrayList Danh sách [] là một dãy các Danh sách như vậy

Vì vậy, những gì bạn nói là An Array (Danh sách đối tượng ArrayList) là CHỈNH SỬA.

Bạn có thể chia sẻ những thử nghiệm của mình không. Các thử nghiệm của riêng tôi khác nhau

import java.util.*; 

public class TestList { 
    public static void main(String ... args) { 
     class MySpecialLinkedList extends LinkedList<ArrayList<Integer>> { 
      MySpecialLinkedList() { 

      } 

      public void foo() { 

      } 


      public Object clone() 
      { 
       return super.clone(); 
      } 
     } 

     List<ArrayList<Integer>> [] someListArray = new MySpecialLinkedList[10]; 
     for (int i = 0; i < 10; ++i) { 
      someListArray[i] = new LinkedList<ArrayList<Integer>>(); 
      for (int j = 0; j < 20; ++j) { 
       someListArray[i].add(new ArrayList<Integer>()); 
       for (int k = 0; k < 30; ++k) { 
        someListArray[i].get(j).add(j); 
       } 
      } 
     } 
    } 
} 
0

Sau khi chạy một số thử nghiệm bổ sung, tôi nghĩ tôi có câu trả lời.

Danh sách <ArrayList> [] thực sự chỉ định một mảng trong đó mỗi phần tử là Danh sách đối tượng ArrayList.

Biên dịch mã như được hiển thị bên dưới cho thấy lý do tại sao phép thử đầu tiên của tôi cho phép tôi sử dụng mảng trong đó mỗi phần tử là Danh sách bất kỳ thứ gì. Sử dụng các kiểu trả về của Danh sách [] và Danh sách trong các phương thức cư trú các mảng không cung cấp cho trình biên dịch đủ thông tin để ngăn chặn các bài tập. Nhưng trình biên dịch đã đưa ra cảnh báo về sự mơ hồ.

Từ quan điểm của trình biên dịch, phương thức trả về Danh sách [] có thể trả về một Danh sách <ArrayList> (đáp ứng tuyên bố) hoặc có thể không. Tương tự, một phương thức trả về một List có thể hoặc không thể trả về một ArrayList.

Dưới đây là trình biên dịch ra:

javac Generics2.java -Xlint: bỏ chọn

 
Generics2.java:12: warning: [unchecked] unchecked conversion 
found : java.util.List[] 
required: java.util.List<java.util.ArrayList>[] 
     someListArray = getArrayWhereEachElementIsALinkedListObject(); 
                   ^
Generics2.java:16: warning: [unchecked] unchecked conversion 
found : java.util.List[] 
required: java.util.List<java.util.ArrayList>[] 
     someListArray= getArrayWhereEachElementIsAListOfLinkedListObjects(); 

Dưới đây là các bài kiểm tra của tôi.

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


public class Generics2 { 

    public static void main(String[] args) { 

     List<ArrayList>[] someListArray; 

     someListArray = getArrayWhereEachElementIsALinkedListObject(); 
     // Why does this satisfy the declaration? 
     //someListArray[0] => LinkedList object holding Strings 

     someListArray= getArrayWhereEachElementIsAListOfLinkedListObjects(); 
     //someListArray[0] => LinkedList object holding LinkedList objects 

    } 

    public static List[] getArrayWhereEachElementIsALinkedListObject() { 
     List[] arrayOfLists = new LinkedList[2]; 
     arrayOfLists[0] = getStringLinkedListAsList(); 
     arrayOfLists[1] = getIntegerLinkedListAsList(); 
     return arrayOfLists; 
    } 

    public static List[] getArrayWhereEachElementIsAListOfLinkedListObjects() { 

     List list1 = new LinkedList(); 
     list1.add(new LinkedList()); 

     List list2 = new LinkedList(); 
     list2.add(new LinkedList()); 

     List[] arrayOfListsOfLinkedLists = new LinkedList[2]; 
     arrayOfListsOfLinkedLists[0] = list1; 
     arrayOfListsOfLinkedLists[1] = list2; 
     return arrayOfListsOfLinkedLists; 
    } 

    public static List getStringLinkedListAsList() { 
     List stringList= new LinkedList(); 
     stringList.add("one"); 
     stringList.add("two"); 
     return stringList; 
    } 


    public static List getIntegerLinkedListAsList() { 
     List intList= new LinkedList(); 
     intList.add(new Integer(1)); 
     intList.add(new Integer(2)); 
     return intList; 
    } 

} 
+0

bạn sẽ có thể chỉnh sửa bài viết gốc của bạn để bao gồm các mã trên mà sẽ tốt hơn so với gửi nó như là một câu trả lời – Jean

17

Câu trả lời là mảng chỉ có thể chứa các loại được sửa đổi. Và các lớp học tổng quát không được thống nhất. Tức là, kiểu "thời gian chạy" của Danh sách <ArrayList> chỉ là Danh sách. Generics bị xóa khi chạy (google "wall of erasure" để biết thêm).

Vì vậy, đây:

List<ArrayList>[] myArray 

thực sự có nghĩa là:

List[] myArray 

Không có cách nào loại an toàn để khai báo những gì bạn đang cố gắng để khai báo. Nói chung, tôi khuyên bạn nên sử dụng Danh sách thay vì một mảng trong trường hợp này. Một số người đã đi xa như vậy để gợi ý rằng các mảng nên được coi là loại không được chấp nhận bây giờ chúng ta có generics. Tôi không thể nói rằng tôi sẵn sàng đi xa nhưng bạn nên xem xét liệu một bộ sưu tập là một lựa chọn tốt hơn bất cứ khi nào bạn đang vẽ một mảng.

Cuốn sách Java Generics and Collections bởi Naftalin và Wadler là một tài liệu tham khảo tuyệt vời cho các câu hỏi mà bạn có thể có về Generics. Hoặc, tất nhiên, số Generics FAQ là tham chiếu trực tuyến chuẩn của bạn.