簡體   English   中英

Java:為未知數量的條目設置數組長度

[英]Java: Setting array length for an unknown number of entries

我正在嘗試用值填充RealVector (來自Apache Commons Math)。 我嘗試使用該類的append方法,但實際上並沒有添加任何內容。 因此,現在我使用的是double[] ,它工作正常,但我事先不知道數組需要多大。

private void runAnalysis() throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
    Double attr;
    double[] data = new double[100]; // TODO: bad.

    int i = 0;
    for (Method m : ParseTree.class.getMethods()) {
        if (m.isAnnotationPresent(Analyze.class)) {
            attr = (Double) m.invoke(this);
            analysis.put(m.getAnnotation(Analyze.class).name(), attr);
            data[i++] = attr * m.getAnnotation(Analyze.class).weight();
        }
    }

    weightedAnalysis = new ArrayRealVector(data);
}

我該如何處理? 這是我的想法:

  1. 遍歷該類並使用批注對方法進行計數,然后使用該大小初始化數組。 但是,這將需要一個額外的循環,並且反射是性能密集的。 (對?)

  2. 為數組選擇任意大小,如果空間用完,則將其加倍。 缺點:需要更多代碼行

  3. 使用List<Double> ,然后以某種方式將Double對象RealVectordoubles以便可以將它們放入RealVector 為列表使用更多的內存。

  4. 只需為起始數組選擇一個很大的大小,並希望它永遠不會溢出。 缺點:這是在請求arrayindexoutofbound錯誤。

  5. 還是我只是使用append(double d)錯誤?

    私有無效runAnalysis()拋出IllegalArgumentException,IllegalAccessException,InvocationTargetException {Double attr; weightedAnalysis =新的ArrayRealVector(data);

     for (Method m : ParseTree.class.getMethods()) { if (m.isAnnotationPresent(Analyze.class)) { attr = (Double) m.invoke(this); analysis.put(m.getAnnotation(Analyze.class).name(), attr); weightedAnalysis.append(attr * m.getAnnotation(Analyze.class).weight()); } } 

    }

RealVector.append()不會修改矢量,而是構造一個新的矢量:[RealVector.append()的Java文檔]( http://commons.apache.org/math/apidocs/org/apache/commons /math/linear/RealVector.html#append(double))解釋:

append

RealVector append(double d)
Construct a vector by appending a double to this vector.
Parameters:
d - double to append.
Returns:
a new vector

請注意,使用RealVector構造向量是一個非常昂貴的操作,因為append()將需要一遍又一遍地復制元素(即,按照您解釋的方式在O(n^2)時間內構造數組O(n^2)

我建議僅在構造過程中使用java的ArrayList<Double> ,然后簡單地轉換為RealVector或您喜歡的任何其他數據抽象。

為什么不使用ArrayList並向其中添加元素?

我建議將3作為一個不錯的選擇。 由於引入了自動裝箱,因此使用Double vs Double是一個最小的問題。

使用RealVector會花費大量的內存和計算時間,因為您想要的是:

RealVector newVector = oldVector.append(d);

append()返回一個新構造的對象,這就是您想要的正確性。

如果您可以在構建上承擔大量開銷,可以看看Apache Commons ArrayUtils ,特別是add(double)和/或toPrimitive(Double)。

您提到您嘗試了append方法,但實際上並沒有添加任何內容。 查看完Javadoc之后,請確保將append方法的結果分配回原始值...您可能已經嘗試過此操作,但以防萬一您忽略了:

RealVector myRealVector = new ArrayRealVector(data);
myRealVector = myRealVector.append(1.0);

換句話說,這不會更改myRealVector:

RealVector myRealVector = new ArrayRealVector(data);
myRealVector.append(1.0);

您可以使用來初始化數組

ParseTree.class.getMethods().lenght

作為初始容量:

double[] buf = new double[ ParseTree.class.getMethods().lenght ];

或更好

DoubleBuffer buf = DoubleBuffer.allocate([ ParseTree.class.getMethods().lenght);

這可能會浪費一些內存,但這是一個安全的解決方案,它取決於循環中是否命中了多少個。

如果願意,可以預先計算要注釋的方法數量,然后為數組分配確切的大小

暫無
暫無

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

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