2012-06-18 24 views
5

好吧,我在Java中製作了一個動態的2D數組,它實現了java.util.Collection接口。我讓我的數組實現它,因爲我希望它具有與正常的Collection相同的功能。但是,我不能實現size()方法,因爲在接口中它返回一個整數,並且2D矩陣可能會溢出一個整數類型。動態二維數組可以實現Java.Collection.size()方法嗎?

這是我班的一個片段,我試圖讓:

public abstract class AbstractMatrix<E> implements Collection<E>{ 
    @Override 
    public long size() { 
     return columns * rows; 
    } 
} 

現在,這是行不通的,因爲「返回類型是Collection<E>.size()不兼容」,如果我更改類型爲int ,列*行可能會溢出。

我知道我不能重寫像這樣的大小方法,但是有沒有什麼辦法可以確保方法返回正確的大小,同時仍然實現了Collection接口?

是的,我知道這是不切實際的,可能永遠不會成爲問題,但我有興趣知道是否有一個好的解決方案。

+0

溢出如矩陣大於45K行×45K列(假設它是正方形)? – assylias

+0

您計劃擁有超過2,147,483,647個元素? –

+0

什麼你能不能做* *有'size'是'欄* rows'?它會讓你對矩陣做什麼? – sudocode

回答

2

雖然你的size實現是值得商榷的,對於Collection#size合同中the javadoc定義:

返回此集合中元素的個數。如果此集合包含多個Integer.MAX_VALUE元素,則返回Integer.MAX_VALUE。

所以,你可以計算出大小爲long,並返回Integer.MAX_VALUE如果它比Integer.MAX_VALUE大。

或者,您可以模仿它在LinkedList#add中的實現方式,例如,size只是簡單地增加並且允許溢出。

-1

我不這麼認爲,您需要使用某種解決方法。你也許可以擴展你的大小來返回負數,並將它們解釋爲無符號的32位整數,這會給你最多40億的變化。

問問自己雖然,你是否真的需要能夠支持這麼多的對象?請記住,40億和改變32位整數將佔用16GB的RAM。使用64位Java,設置爲全空的40億長陣列Object將佔用32GB,因爲64位Java上的引用是64位。這甚至不考慮用於實際實例化許多類的內存,這很可能會高得多。

+0

是的,我知道這是不切實際的有一個二維數組會溢出這樣的,但我是問只是爲了看看是否有解決方案。 – Wires77

+0

你有沒有考慮過查看ArrayList的代碼。爲什麼你的返回類型需要很長? – branchgabriel

+0

mugafuga:是的ArrayList集合,並且只有'INT大小()',沒有'長尺寸()'。 – Wug

0

如果你真的擔心足夠大的矩陣可能溢出,你可以通過檢查結果大小(初始化或調整大小)是否仍然在整數範圍內並確保不會發生,異常,如果這將是情況

2

假設你願意擁有一個8GB的陣列 - 一個二維陣列的最小尺寸,它將以其總大小溢出int--並假設你願意對該集合做任何有趣的事情,比如迭代(至少爲迭代花費幾分鐘)...

我相信,典型的做法是要麼回落到實施Iterable,而不是Collection,或只返回Integer.MAX_VALUE,由指定的Javadoc:

返回此集合中元素的個數。如果此集合包含多個Integer.MAX_VALUE元素,則返回Integer.MAX_VALUE。

+1

有趣的是,LinkedList#add可以讓大小溢出而無需檢查。 – assylias

+0

這並不令人感到意外;在你開始遇到這類問題之前,你的記憶通常會耗盡很久。 (另外,很難想象LinkedList的用法可以擴展到許多元素。) –