[英]What is the best practice for setting the initial capacity of an ArrayList that is not always used?
[英]arraylist is always created with a constant capacity
我正在嘗試計算給定行號的帕斯卡三角形。 我正在使用遞歸。
我的代碼如下:
public static List<Integer> getRow(int rowIndex) {
if (rowIndex == 1){
List <Integer> list = new ArrayList(rowIndex+1);
list.add(1);
return list;
}
else{
List<Integer> oldList = getRow(rowIndex -1);
List <Integer> list = new ArrayList(rowIndex+1);
int temp = 0;
list.add(0,1);
list.add(list.size()-1,1);
System.out.println("rowIndex "+rowIndex);
for (int i = 1; i < list.size()-1; i ++){
temp = oldList.get(i) + oldList.get(i-1);
list.add(i,temp);
}
return list;
}
}
無論我嘗試獲取哪一行,它總是返回[1,1]。 我嘗試插入打印語句。 我注意到無論rowIndex是什么,列表的大小始終為2。
List <Integer> list = new ArrayList(rowIndex+1);
上面的行不是創建ArrayList的正確方法嗎? 好像我的arraylist總是size = 2;
您會誤解ArrayLists
工作原理,因此您應該閱讀Javadoc 。
簡而言之,構造函數的參數定義了內存中ArrayList的初始大小,而不是最大大小。 如果實例化一個new ArrayList<Integer>(2)
則僅意味着jvm為兩個Integer分配了足夠的前期空間,並且當您添加第三個元素時,jvm將增大ArrayList的大小,以便允許您添加更多元素。
此外,僅當在此位置添加了元素時,才可以使用get()
訪問ArrayList
位置。
最后,請記住,在特定位置add
會右移所有元素。 因此,如果先add(10,1)
然后再add(2,4)
,則第一個添加項將向右移動。
回到您的問題,如果您絕對要使用ArrayList
而不是array
,則必須使用正確的大小初始化ArrayList
,然后在正確的位置set
值。
這是一個可行的解決方案:
// the method with your algorithm which has been slightly modified
public static List<Integer> getRow(final int rowIndex) {
// notice that I call a helper method which initialises correctly the ArrayList
final List<Integer> list = init(rowIndex);
if (rowIndex == 1) {
// notice that I set the value at a given position
// I can only do it because I initialised all values to 0 first
list.set(0, 1);
} else {
final List<Integer> previousRowList = getRow(rowIndex - 1);
// again, I set values...
list.set(0, 1);
list.set(rowIndex - 1, 1);
for (int i = 1; i < (list.size() - 1); i++) {
// set again...
list.set(i, previousRowList.get(i - 1) + previousRowList.get(i));
}
}
// lets print out the row
System.err.println(list);
// then return it
return list;
}
public static List<Integer> init(final int size) {
// passing the size is overkill, but well...
final List<Integer> list = new ArrayList<Integer>(size);
// fill the ArrayList with zeros
for (int i = 0; i < size; i++) {
list.add(i, 0);
}
// then return it
return list;
}
public static void main(final String[] args) {
getRow(Integer.parseInt(args[0]));
}
如果運行它,將會得到一個(不是很好,但是可以工作的)帕斯卡三角形。 如果需要11行,則結果如下:
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
[1, 6, 15, 20, 15, 6, 1]
[1, 7, 21, 35, 35, 21, 7, 1]
[1, 8, 28, 56, 70, 56, 28, 8, 1]
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
[1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1]
希望能幫助到你 !
我認為您正在誤解數據結構。
數組列表是在數組頂部實現的LIST。 在構造函數中設置數組的大小是一種將控制權交給開發人員以控制數組的初始大小的方法(由於類本身管理數組的大小,因此這幾乎是沒有必要的,因此請忽略此參數)。 因此,數組列表的大小實際上就是列表的大小,即元素的數量,而不是構造函數中指定的基礎數組中存儲區的數量。
如果知道所需數組的大小,並且想要在特定位置獲取和添加,請使用標准數組,而不是數組列表。
但是,我認為如果您移動代碼,代碼將起作用
list.add(list.size()-1,1);
到for循環之后(實際上我很驚訝它沒有拋出索引超出范圍的異常)。 而且由於您是從左到右,因此您的添加項都不需要指定索引,因為它只會將其添加到現有列表的末尾。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.