[英]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);
}
我該如何處理? 這是我的想法:
遍歷該類並使用批注對方法進行計數,然后使用該大小初始化數組。 但是,這將需要一個額外的循環,並且反射是性能密集的。 (對?)
為數組選擇任意大小,如果空間用完,則將其加倍。 缺點:需要更多代碼行
使用List<Double>
,然后以某種方式將Double
對象RealVector
為doubles
以便可以將它們放入RealVector
。 為列表使用更多的內存。
只需為起始數組選擇一個很大的大小,並希望它永遠不會溢出。 缺點:這是在請求arrayindexoutofbound錯誤。
還是我只是使用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.