2013-12-09 50 views
1

我已經長100 float[] array有沒有一種方法,我可以選擇(僞):選擇子數組而不復制到新緩衝區中?

x = array[10:19]; 

要獲得元素10,11,12,...,19沒有複製到另一國緩衝區?我在移動應用程序中,我不想浪費空間或時間來做這件事。我寧願只參考系統使用的指針array。 謝謝

+0

您如何查看結果?使用浮動時,唯一不復制的方法是引用原始數組。所以,如果你保持索引像'start = 10'和'end = 19',那麼你可以像'array [start +(length - 1)]那樣訪問它' –

回答

2

執行此操作的最有效方法是使用System.arrayCopy(),這比使用循環手動複製要快得多並且效率更高。它將需要另一個數組,但是你使用的任何方法(不僅僅是傳遞原始數組以及表示要使用的偏移量的幾個int)將會執行此操作,而且它相對便宜 - 內存消耗位通常是它引用的對象而不是數組本身,並且它們不被複制。

0

使用簡單循環的問題是什麼?對象在java中被稱爲引用。 因此,執行復制數組不會複製對象。

float[] subarray = new float[10]; 
for(int i = 10, j = 0; i < 19; i++, j++) { 
    subarray[j] = x[i]; 
} 

array[0]是的x[0]的對象的引用。

編輯:這僅適用於對象,我不知道這是否也適用於float

+0

你是對的,我看錯了這個問題。 – Haneev

2

沒有,有沒有API來做到這一點。最接近的解決方案,這將是建立自己的類包裝現有的陣列,並執行重新索引:

class SubArray { 
    private final float[] data; 
    private final int offset; 
    private final int length; 
    public SubArray(float[] data, int offset, int length) { 
     this.data = data; 
     this.offset = offset; 
     this.length = length; 
    } 
    public float get(int index) { 
     if (index >= length) throw ... 
     return data[index + offset]; 
    } 
    public void set(int index, float value) { 
     if (index >= length) throw ... 
     data[index + offset] = value; 
    } 
} 

如果你需要的是一個新的對象,它的行爲就像在各方面的數組的結果,包括索引操作符,您需要複製一份。

2

更新)前提條件:您應該將數據存儲在Float[]而不是float[],應該將性能降至最低。

您可以使用:Arrays.asList(array).subList(10, 20)

Arrays.asList(array)執行以下操作:

返回由指定數組支持的固定大小的列表。 (對返回列表進行「直寫」到數組的更改。)此方法充當基於數組和基於集合的API之間的橋樑,並結合使用Collection.toArray()。返回的列表是可序列化的並實現RandomAccess。

Source

然後.subList(10, 20)回報你一個List

然後,如果你真的想在高端陣列的工作,你可以採取以下幾行:

List<Float> subList = Arrays.asList((Float[])array).subList(10, 20); 
Float[] subArray = subList.toArray(new Float[subList.size()]); 

更新)變更Arrays.asList(array)Arrays.asList((Float[])array),使得它現在是正確的。

從文檔:

返回包含在該列表中正確序列中的所有元素的數組(從第一個到最後一個元素);返回數組的運行時類型是指定數組的運行時類型。如果列表符合指定的數組,則返回其中。否則,將使用指定數組的運行時類型和此列表的大小分配一個新數組。

如果列表符合指定數組並且有空餘空間(即數組的元素多於列表),緊接列表結尾的數組中的元素將設置爲空。 (只有當調用者知道該列表中不包含任何空元素時,纔有助於確定列表的長度。)

與toArray()方法類似,此方法充當基於數組和基於collection的方法之間的橋樑,基於API的API。此外,該方法允許精確控制輸出數組的運行時類型,並且在某些情況下可以用於節省分配成本。

假設x是已知只包含字符串的列表。下面的代碼可以用來將該列表轉儲到字符串的新分配的數組:

Source

這將確保沒有數據被浪費掉了,唯一要小心,可自動裝箱。

更新:更改我的答案,使其現在在一個先決條件下是正確的。

+0

-1。這不適用於原始數組,只適用於對象數組。如果你嘗試它,你會得到一個單元素列表'。 –

+0

@LouisWasserman更新了答案。結果:可能會添加一個小的性能命中(自動裝箱),但它現在可以正常工作,不再需要-1。 – skiwi

+0

toArray()函數將它複製到您的新緩衝區中。這違背了OP的要求。 –