在指定索引处将对象添加到ArrayList中

160

我认为这是一个相当简单的问题,但我无法正确地解决它。

我有一个空的ArrayList:

ArrayList<object> list = new ArrayList<object>();

我有一些对象,想要向其中添加对象,并且每个对象必须位于特定的位置。然而,必须允许以任何可能的顺序添加它们。当我尝试这样做时,它不起作用,会抛出一个IndexOutOfBoundsException异常:

list.add(1, object1)
list.add(3, object3)
list.add(2, object2)

我尝试过用null填充 ArrayList ,然后执行上述操作。 这种方法可行,但我认为它是一个可怕的解决方案。 有没有其他方法可以做到这一点?


7
由于列表为空,您无法访问不存在的列表位置,因此会出现IndexOutOfBoundsException(索引越界异常)... - Vic
1
有没有一种方法可以在不用填充空对象的情况下创建该位置?对我来说,这似乎是一个非常奇怪的解决方案。 - J. Maes
1
我不这么认为...如果你需要以随机顺序添加对象,你就得寻找另一种方法来实现。例如,使用一个典型的数组:'Object[]',然后你就不需要填充它,只需初始化即可。 - Vic
1
@Maethortje 这并不是一个奇怪的问题。查找稀疏列表,http://reference.wolfram.com/mathematica/tutorial/SparseArrays-ManipulatingLists.html 是一篇不错的文章。在Java中,使用索引作为键的Map可能是最简单的方法。 - Miserable Variable
@Vic 即使我声明了一个带有大小的ArrayList,你仍然无法访问索引吗?我也遇到了这种outofbounds错误,原因是相同的吗?谢谢。 - dsfdf
2
即使您声明了大小,它也不会初始化列表,而是声明要在内存中保留多少空间。在我看来,列表是具有指向下一个元素的指针的元素数组。如果您尝试在第二个为空(或null)时将元素添加到第三个位置,则没有指针可以帮助您知道它是第三个元素。1->2->3没问题,但是1->*->3这里就有问题了... - Vic
14个回答

234
你可以像这样做:
list.add(1, object1)
list.add(2, object3)
list.add(2, object2)

在将object2添加到位置2之后,它会将object3移动到位置3。

如果您希望object3始终位于position3,我建议您使用HashMap,其中position作为键,object作为值。


3
哈希表确实能够解决这个问题。我想我会选择它,因为当位置2没有对象时,似乎无法在位置3添加任何东西。 - J. Maes
翻译:简短但最佳答案。其他的都是走错了方向。 - Shabbir Dhangot
一种建设性逻辑! - Arsal Imam

37

您可以使用对象数组并将其转换为ArrayList -

Object[] array= new Object[10];
array[0]="1";
array[3]= "3";
array[2]="2";
array[7]="7";

List<Object> list= Arrays.asList(array);

ArrayList将会是- [1, null, 2, 3, null, null, null, 7, null, null]


3
一个缺点是你必须事先知道尺寸大小。 - Daniel Hári

17

如果是这样的话,为什么不考虑使用普通的数组,初始化容量并将对象放置在你想要的索引处。

Object[] list = new Object[10];

list[0] = object1;
list[2] = object3;
list[1] = object2;

你初始化了ArrayList的容量,但没有初始化它的大小。大小被定义为元素的数量,当索引大于大小时会出现异常... - Vic
我将容量初始化为10,但是在添加对象时仍然出现IndexOutOfBoundsException异常。使用ensureCapacity更改容量也是如此。目前唯一有效的方法是填充null... - J. Maes
@Maethortje 寻找“size”和“capacity”的区别...例外情况是当索引>大小而不是>容量时发生..... - Vic
@medopal 在我的应用程序运行时,可能会创建新的对象,因此我选择了列表来添加它们。 - J. Maes
虽然不完全符合J.Maes的要求,但我认为这个答案是一个好的建议。如果您确实知道列表的大小,则在这种情况下,数组优于数组列表。感谢Medopal,+1! - shecodesthings
显示剩余2条评论

15

你也可以重写ArrayList,在你想添加的元素和当前size之间插入nulls。

import java.util.ArrayList;


public class ArrayListAnySize<E> extends ArrayList<E>{
    @Override
    public void add(int index, E element){
        if(index >= 0 && index <= size()){
            super.add(index, element);
            return;
        }
        int insertNulls = index - size();
        for(int i = 0; i < insertNulls; i++){
            super.add(null);
        }
        super.add(element);
    }
}

那么你可以在ArrayList的任何位置添加元素。例如,这个main方法:

public static void main(String[] args){
    ArrayListAnySize<String> a = new ArrayListAnySize<>();
    a.add("zero");
    a.add("one");
    a.add("two");
    a.add(5,"five");
    for(int i = 0; i < a.size(); i++){
        System.out.println(i+": "+a.get(i));
    }
}   

从控制台输出,该结果如下:

0: zero

1: one

2: two

3: null

4: null

5: five


1
注意!如果你在最后加上a.add(3, "three");,第五个元素将被推向前面。你会得到:"6: five"。 - Alex Busuioc

11

我想引起你的注意,参考ArrayList.add文档,该文档指出如果索引超出范围(index < 0 || index > size()),则会抛出IndexOutOfBoundsException异常。

在调用list.add(1, object1)之前,请检查列表的size()


你说得对 @Hemal,@Maethortje 为什么不在向列表添加元素之前检查列表的大小呢?检查你要添加的位置是否小于列表的大小,如果不是,那么你可以直接执行普通的 list.add("element"); - Rakesh
2
据我理解,“问题”是即使在第2个位置没有元素的情况下,在第3个位置添加元素。 - Vic
@Vis 这是一个稀疏列表 - 请参阅我对问题的评论。 - Miserable Variable

5

你需要用null填充空索引。

while (arraylist.size() < position)
{
     arraylist.add(null);
}

arraylist.add(position, object);

3
@Maethortje 

The problem here is java creates an empty list when you called new ArrayList and 

在尝试将元素添加到指定位置时,您遇到了IndexOutOfBound错误,这意味着该列表应该有一些元素在它们的位置上。

请尝试以下操作:

/*
  Add an element to specified index of Java ArrayList Example
  This Java Example shows how to add an element at specified index of java
  ArrayList object using add method.
*/

import java.util.ArrayList;

public class AddElementToSpecifiedIndexArrayListExample {

  public static void main(String[] args) {
    //create an ArrayList object
    ArrayList arrayList = new ArrayList();

    //Add elements to Arraylist
    arrayList.add("1");
    arrayList.add("2");
    arrayList.add("3");

    /*
      To add an element at the specified index of ArrayList use
      void add(int index, Object obj) method.
      This method inserts the specified element at the specified index in the
      ArrayList.  
    */
    arrayList.add(1,"INSERTED ELEMENT");

    /*
      Please note that add method DOES NOT overwrites the element previously
      at the specified index in the list. It shifts the elements to right side
      and increasing the list size by 1.
    */

    System.out.println("ArrayList contains...");
    //display elements of ArrayList
    for(int index=0; index < arrayList.size(); index++)
      System.out.println(arrayList.get(index));

  }
}

/*
Output would be
ArrayList contains...
1
INSERTED ELEMENT
2
3

*/

我理解导致错误的问题。似乎我必须先添加对象到后续位置,然后才能添加对象到该位置。当我添加时,我没有处理我想要添加的所有对象。你认为添加null对象是一个合适的解决方案吗? - J. Maes
@Maethortje 这样做并不太公平,因为这只是一个hack :) - Sankalp
以下是有关编程的内容,请将其从英语翻译成中文。仅返回翻译后的文本:您需要从第一段中删除代码示例引号。 - Jalal Sordo

2
这是一个可能的解决方案:
list.add(list.size(), new Object());

2
这个小的while循环怎么样作为解决方案?
private ArrayList<Object> list = new ArrayList<Object>();

private void addObject(int i, Object object) {
    while(list.size() < i) {
        list.add(list.size(), null);
    }
    list.add(i, object);
}
....

addObject(1, object1)
addObject(3, object3)
addObject(2, object2)

1
你应该使用设置(set)而不是添加(add),以替换索引处的现有值。
list.add(1, object1)
list.add(2, object3)
list.set(2, object2)

列表将包含[object1,object2]。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接