簡體   English   中英

打印任何類型的ArrayList元素的一般方法

[英]A general method to printout elements of an ArrayList of any type

出於實踐目的,我試圖編寫一個通用方法來通過調用它的.toString()方法來顯示ArrayList的元素。 讓我們假設.toString()做我想做的事。

我想出了下面的解決方案,我的輸入ArrayListObject類型:

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> ,即使IntegerObject

您需要在方法的參數中使用通配符,因為您不關心泛型類型參數的類型。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM