2009-09-26 88 views
49

如何在Java中獲得ArrayList的數組切片?具體來說,我想要做這樣的事情:如何從Java中的ArrayList切出一個ArrayList?

ArrayList<Integer> inputA = input.subList(0, input.size()/2); 
// where 'input' is a prepouplated ArrayList<Integer> 

所以我預計這個工作,但Java返回List - 所以它是不兼容的。當我嘗試投射時,Java不會讓我。我需要一個ArrayList - 我該怎麼辦?

+4

你爲什麼要堅持使用'ArrayList'?我認爲你可能會缺乏一點理解界面是如何工作的,因爲'List'和'ArrayList'不是「不兼容的」-ArrayList'實現'List','List'可能包含你需要的所有必要的方法。 – Bombe 2009-09-26 11:59:48

+2

我堅持使用ArrayList,因爲它使用剛性方法原型的inteview問題。我顯然確實缺乏理解,因爲subList應該返回一個List類型,但我不能將返回的List轉換爲ArrayList。所以你告訴我的人.. – 2009-09-26 20:48:59

+4

他完全有可能需要一個'ArrayList',因爲他需要調用一個接受'ArrayList'的方法。可以說,這樣的方法設計得不好,應該接受'List',但是這種情況不僅會出現在面試問題上,而且會出現在別人寫的代碼中,不能隨便去改變。同事和圖書館並不總是完美的。 – Gravity 2012-01-12 20:03:40

回答

86

在Java中,在API中使用接口類型而不是具體類是一種很好的做法。

你的問題是你正在使用ArrayList(可能在很多地方),你真的應該使用List。因此,您爲自己製造了一些問題,並列出了一個不必要的限制,即該列表爲ArrayList

這是你的代碼應該是什麼樣子:

List input = new ArrayList(...); 

public void doSomething(List input) { 
    List inputA = input.subList(0, input.size()/2); 
    ... 
} 

this.doSomething(input); 

你提出的「解決方案」的問題是/是這樣的:

new ArrayList(input.subList(0, input.size()/2)) 

通過使副本工作子列表。這不是正常意義上的切片。此外,如果子列表很大,則複製將會很昂貴。


如果您是通過API的,你不能改變,這樣你必須聲明inputA作爲ArrayList,你可能能夠實現的ArrayList自定義子類的限制,其中subList方法返回ArrayList的一個子類。然而:

  1. 這將是很多工作來設計,實施和測試。
  2. 您現在已經在您的代碼庫中添加了重要的新類,可能依賴於ArrayList類的未記錄方面(因此「可能會更改」)方面。
  3. 您需要更改代碼庫中的相關位置,以創建ArrayList實例來創建子類的實例。

「複製陣列」解決方案更實際...銘記這些不是真正的切片。

+3

實際上,subList不會複製;它將視圖返回到原始列表(http://docs.oracle.com/javase/6/docs/api/java/util/List.html#subList%28int,%20int%29) – Matthew 2014-08-25 19:41:20

+2

其實@Matthew,I指的是OP的自我回答,他這樣做:'new ArrayList(input.subList(0,input.size()/ 2))' – 2014-08-25 22:33:49

6

如果沒有現有的方法,那麼我想你可以迭代從0到input.size()/2,每個連續的元素並將其附加到一個新的ArrayList。

編輯:其實,我覺得你可以採取的清單,並用它來實例化使用one of the ArrayList constructors一個新的ArrayList。

+2

這正是我所做的(在我閱讀你的編輯之前張貼了我的答案)。感謝:) – 2009-09-26 07:32:14

+0

但是,*複製列表以創建一個新的ArrayList。 – Joren 2009-09-26 07:33:31

+2

@BT - 爲了記錄,這不是「切片」通常在這種情況下表示的術語。 – 2012-06-19 22:56:51

-4

這就是我解決它的方法。我忘記了這個子列表是對原始列表中元素的直接引用,所以它爲什麼不起作用是有道理的。 ArrayList inputA = new ArrayList(input.subList(0,input.size()/ 2));}};}}

2

我已經找到一種方法,如果你知道元素的startIndex和endIndex一個需要從ArrayList中

刪除讓al是原來的ArrayList和startIndexendIndex來開始和結束指數從數組分別取出:

al.subList(startIndex, endIndex + 1).clear(); 
相關問題