[英]A general method to printout elements of an ArrayList of any type
出於實踐目的,我試圖編寫一個通用方法來通過調用它的.toString()
方法來顯示ArrayList
的元素。 讓我們假設.toString()
做我想做的事。
我想出了下面的解決方案,我的輸入ArrayList
是Object
類型:
public void printArralyList(ArrayList<Object> list){
for(Object o:list){
System.out.print(o.toString());
}
System.out.println();
}
但它不會起作用!
printArralyList(new ArrayList<Integer>(Arrays.asList(1,2,3,5,8,13,21)));
我得到的編譯錯誤是
The method printArralyList(ArrayList<Object>) is not applicable
for the arguments (ArrayList<Integer>
我怎么解決這個問題?
ArrayList<Integer>
不是ArrayList<Object>
,即使Integer
是Object
。
您需要在方法的參數中使用通配符,因為您不關心泛型類型參數的類型。
public void printArralyList(ArrayList<?> list){
順便說一句,您可以讓您的方法采用List
而不是ArrayList
,並且不需要在ArrayList
包裝Arrays.asList
的返回:
public void printArralyList(List<?> list){
和
printArralyList(Arrays.asList(1,2,3,5,8,13,21));
會工作。
你不需要泛型或通配符。 您只需要一個簡單的方法,它不會為參數指定任何類型,以便您可以隨時傳入ArrayList。
public void printArralyList(ArrayList list){
for (Object o:list){
System.out.print(o.toString());
}
System.out.println();
}
出現錯誤的原因由rgettman在https://stackoverflow.com/a/21996188/中解釋
public static void printIterable(Iterable<?> iterable)
{
for (Object object : iterable)
{
System.out.print(object);
}
System.out.println();
}
這可以與ArrayList<Integer>
參數一起使用,也可以與LinkedHashSet<JComponent>
,或者實現Iterable
接口的任何其他內容....
回答你的問題。
聲明ArrayList不等於ArrayList。 即使從類型層次結構中的Object
傳遞Integer
也是如此。
需要記住的重要一點是,當您聲明Collection<String> myStrings
,您告訴編譯器,對於變量myString
只能分配在String
類型上創建的類的實例,並且是Collections。
Collection<Object> myObjects;
myObjects = new ArrayList<String>(); //Exception
myObjects = new HashSet<String>(); //Exception
myObjects = new HashSet<Object>(); //Valid
myObjects = new ArrayList<Object>(); //Valid
myObjects = new ArrayList<Integer>(); //Exception
為了解決這樣的問題,java提供了一組允許你傳遞它的Wildcars 。
有三種類型的意志卡支持各種差異 。
<? extends T> - Covariance
<? super T> - Contravariance
<?> - Invariance/
有關它們的規則稱為PECS
由於我們要使用列表元素,要刪除編譯錯誤,您應該使用協方差。
Collection<? extends Object> myObjects;
myObjects = new ArrayList<String>(); //Valid
myObjects = new HashSet<String>(); //Valid
myObjects = new HashSet<Object>(); //Valid
myObjects = new ArrayList<Object>(); //Valid
myObjects = new ArrayList<Integer>(); //Valid
在Java中,每個類都是從對象傳遞的,所以<? extends>
<? extends>
在功能上等於<?>
,這就是rgettman提出的答案
Java中的集合框架由泛型支持。 您應該熟悉它們以從框架中充分受益。
另一種解決方法是從這樣的通用方法中受益:
public static <T> void printList<Iterable<T> iterable) {
for(T element : iterable){
System.out.printf("%s ",element);
}
System.out.println();
}
靜電為什么?
對static方法的調用更快,並且此方法與任何類成員無關。
什么是 ?
這是通用方法的聲明。 它允許您定義泛型參數的值。 Java非常熱衷於它可以自己提取它在版本7中的大多數情況。
如果用Iterable<String>
調用該方法,那么T的值將是String
如果是Iterable,那么是'Integer'。
為什么可以進行?
Iterable是一個簡單的界面,允許您使用for-each外觀 。 這意味着您將能夠遍歷類定義實現它的所有對象。
為什么printf?
printf函數使用Formatter ,它的好處是兩個 - 如果element
實例被賦值為null,那么如果你將它o.toString()
,你將不會得到空指針異常。
什么東西少了 ?
在那個實現中仍然缺少兩件事 - 輸入驗證 - 將元素與昏迷分開的正確輸出格式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.