arraylist总是以恒定的容量创建

时间:2014-11-08 02:03:32

标签: java arraylist

我正在尝试计算给定行号的pascal三角形。我正在使用递归。

我的代码如下:

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]。我试着插入print语句。我注意到无论rowIndex是什么,列表的大小总是2。

 List <Integer> list = new ArrayList(rowIndex+1);

上面的行不是创建ArrayList的正确方法吗?好像我的arraylist总是有size = 2;

2 个答案:

答案 0 :(得分:2)

你误解了ArrayLists的工作方式,你真的应该read the Javadoc

简而言之,构造函数的参数定义了内存中ArrayList的初始大小,而不是最大大小。如果你实例化一个new ArrayList<Integer>(2)它只意味着jvm为两个整数分配了前期足够的空间,并且当你添加第三个元素时,jvm会增加ArrayList的大小,以便你可以添加更多的元素。

此外,只有在此位置添加了元素时,您才能使用ArrayList访问get()位置。

最后,请记住,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]

希望它有所帮助!

答案 1 :(得分:1)

我认为你错过了解释数据结构。

数组列表是在数组之上实现的LIST。在构造函数中设置数组的大小是一种控制开发人员控制数组初始大小的方法(由于类管理数组大小本身,这很少是必要的 - 所以只留下这个参数)。因此,数组列表的大小实际上是列表的大小,即元素的数量,而不是构造函数中指定的基础数组中的桶的数量。

如果您知道所需数组的大小,并且想要在特定位置获取和添加,请使用标准数组,而不是数组列表。

但是,我认为如果移动

,您的代码将会有效
list.add(list.size()-1,1);

到你的for循环之后(我实际上很惊讶它没有抛出索引超出范围的异常)。因为你是从左到右,所以你的添加都不需要指定索引,因为它只是将它添加到现有列表的末尾。