簡體   English   中英

將 double[] 轉換為不可變列表的成本更低的方法

[英]Less expensive way of converting a double[] to an immutable list

我想將數組double[]轉換為不可變集合,以便在值 object 中使用。 但是,我正在處理一個非常大的數組,並且不斷收到錯誤java.lang.OutOfMemoryError: Java heap space

我目前正在使用

Collections.unmodifiableList(DoubleStream.of(myArray).boxed().collect(Collectors.toList()));

我認為這是因為我的程序用完了 memory。 有沒有更便宜的方法可以將 double[] 轉換為不可變列表?

創建自己的List<Double>怎么樣? 如果您實現AbstractList<Double> ,您只需要為不可修改的列表實現兩種方法:

class MyDoubleList extends AbstractList<Double> implements RandomAccess {

    private double[] backingArray;

    public MyDoubleList(double[] backingArray) {
        this.backingArray = backingArray;
    }

    @Override
    public Double get(int index) {
        return backingArray[index];
    }

    @Override
    public int size() {
        return backingArray.length;
    }

    // adding other list methods should be trivial...
}

用法:

List<Double> list = new MyDoubleList(myBigDoubleArray);

請注意,如果更改后備數組,列表內容也會更改。 為了防止這種情況,您通常會復制傳入的數組,但由於復制數組可能會導致 out of memory 異常,所以我沒有這樣做。


或者,如果您使用 Guava,請使用Doubles.asList(myBigDoubleArray) ,它的作用基本相同。 感謝喬的建議!

流非常適合函數式編程和可讀性,但當性能是主要問題時應避免使用。 他們創建了不必要的額外對象。

Also surprisingly, arrays of the double primitive types consume more memory than their wrapper class Double arrays (ref: https://www.baeldung.com/java-primitives-vs-objects )

使用Double object 數組而不是雙原語,然后運行:

Collection<Double> l = Collections.unmodifiableCollection(Arrays.asList(myArray));

我比較了這兩種方法

    public static void main(String[] args) {
        int len = 1000000;
        Double[] myArray = new Double[len];
        for (int i = 0; i < len; i++) {
            myArray[i] = Math.random();
        }
        Collection<Double> l = Collections.unmodifiableCollection(Arrays.asList(myArray));
        long totalMem = Runtime.getRuntime().totalMemory();
        long usedMem =  totalMem - Runtime.getRuntime().freeMemory();
        System.out.println("totalMem="+humanReadableByteCountBin(totalMem));
        System.out.println("usedMem=" + humanReadableByteCountBin(usedMem));
        System.out.println("l has " + l.size() + " items ");
    }

stream 方法使用 48Mb,而Arrays.asList使用 Double 使用 28Mb。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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