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


142

我认为这是一个非常简单的问题,但我不知道如何正确执行此操作。

我有一个空的arraylist:

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

我有一些要添加的对象,每个对象必须位于某个位置。但是,有必要可以按每种可能的顺序添加它们。当我尝试此操作时,它不起作用,并且显示IndexOutOfBoundsException

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

我曾尝试是填充ArrayListnull,然后做以上。它有效,但是我认为这是一个可怕的解决方案。还有另一种方法吗?


7
由于列表为空,并且无法访问不存在的列表位置,因此会收到IndexOutOfBoundsException ...
维克(Vic)

1
有没有一种方法可以创建该位置而不用空对象填充列表?对我来说,这似乎是一个非常奇怪的解决方案。
J. Maes

1
我不这么认为...如果需要按随机顺序添加对象,则必须寻找另一种方法。例如,使用典型数组:“ Object []”,则不应不用为了填补它,只是初始化
维克

1
@Maethortje这不是一个奇怪的问题。查找稀疏列表,reference.wolfram.com / mathematica / tutorial /… 似乎是一篇好文章。但是在Java中,以索引为键的Map可能是最简单的方法。
可悲的变量

2
@Pan即使您声明大小。它只是不初始化列表,而是声明要在内存中保留多少空间。如我所见,列表是元素数组,还具有指向数组的指针。下一个元素。如果在第二个为空(或为null)时尝试将元素添加到第三位置,则没有指针可以帮助您知道它是第三个元素。.:1-> 2-> 3可以,但是1- > *-> 3这里您有问题...
Vic

Answers:


209

您可以这样做:

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

将对象2添加到位置2后,它将把对象3移动到位置3。

如果您想让object3一直处于position3,我建议您使用HashMap,将position作为键,将object作为值。


3
哈希图确实可以解决这个问题。我想我会去为那一个,因为它似乎并不像我可以在位置3添加的东西时,有在位置2,没有对象
J.梅斯

简短但大多数答案。其他人则走错了路
Shabbir Dhangot

建设性的逻辑!
Arsal Imam

31

您可以使用对象数组并将其转换为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]


2
缺点之一是您必须事先知道尺寸。
DanielHári'17

17

如果是这样,那么为什么不考虑使用常规数组,则初始化容量并将对象放在所需的索引处。

Object[] list = new Object[10];

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

您需要初始化容量,而不是'ArrayList'的大小。大小定义为元素数,并且当索引>大小时,异常就会出现...
Vic

@Vic,我一开始看错了问题,但感谢您的提示。
medopal's

我将容量初始化为10,但是在添加对象时仍然得到IndexOutOfBoundsExceptopn。与确保容量更改容量相同。目前唯一有效的方法是用null填充...
J. Maes

@Maethortje寻找“大小”和“容量”之间的区别...例外情况是在索引>大小时出现,而不是在索引>容量时出现..
Vic

正如大家提到的,您要在索引3处添加一个对象,而列表的大小仍为1。这是不可能的。添加在特定的指数是允许的,只要该指数是列表的边界之内,例如,如果您的列表中有3个对象,你不能在指数为100添加一个对象
medopal

14

您也可以重写ArrayList以在您的大小和要添加的元素之间插入null。

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中的任何位置添加。例如,此主要方法:

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:零

1:1

2:两个

3:空

4:空

5:五


9

我提请您注意说明ArrayList.add文档IndexOutOfBoundsException如果索引超出范围,则会抛出 该文档index < 0 || index > size()

size()致电前请先检查清单中的list.add(1, object1)


您是正确的@ Hemal,@ Maethortje为什么在将元素添加到列表之前不检查列表的大小?检查您要添加的位置是否小于列表的大小,如果不是,则可以正常进行操作list.add("element");
Rakesh

1
据我了解,“问题”是在第3位,即使没有在位置2的元素......要添加的元素
维克

@Vis是一个稀疏列表-请参阅我对问题的评论。
可悲的变量,


2
@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

*/

我了解导致我的错误的问题。看来我必须先向后续位置添加对象,然后才能向该位置添加对象。添加的那一刻,我并没有处理掉所有要添加的对象。您认为添加空对象是一种合适的解决方案吗?
J. Maes

@Maethortje这样做不是很公平,因为它只是一个小技巧:)
Sankalp

您需要从第一段中删除代码示例引号。
Jalal Sordo

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)

2

这是一个可能的解决方案:

list.add(list.size(), new Object());

1

我认为medopal的解决方案是您所需要的。

但是,另一个替代解决方案是使用HashMap并使用键(整数)来存储位置。

这样,您一开始就不需要使用null等填充它,只需在进行操作时在地图上粘贴位置和对象即可。如果需要,您可以在末尾写几行以将其转换为List。


因为按键排序,TreeMap更好吗?
丹尼尔·哈里(DanielHári)'17

1

假设您要在某个位置添加项目,则列表大小必须大于该位置。

add(2, item):此语法的意思是,将位置2的旧项目移到下一个索引,然后将其添加到第二位置。

如果在第二个位置没有项目,那么这将不起作用,它将引发异常。

这意味着如果您想添加一些东西position 2,

您的清单大小必须至少为(2 + 1) =3,以便在0,1,2 Position.

通过这种方式,可以确保安全访问位置2,并且不会有异常。


2
当我通知您答案时,我只是路过...实际上,在我们插入新项目时,索引必须小于或等于列表的实际长度。例如:列表大小为2:在索引2中添加将起作用。在索引3中添加将引发异常。(经过测试)
Houssem Chlegou

0

如果您使用的是Android风格的Java,则建议使用SparseArray。与Map相比,这是一种内存效率更高的整数到对象的映射,并且更易于迭代


0

有点晚,但希望对某人仍然有用。

向商品中的特定位置添加商品的2个步骤 ArrayList

  1. add 将项目中的特定索引空项目 ArrayList
  2. 然后set,在需要时按需要提供职位。

        list = new ArrayList();//Initialise the ArrayList
    for (Integer i = 0; i < mItems.size(); i++) {
        list.add(i, null); //"Add" all positions to null
    }
       // "Set" Items
        list.set(position, SomeObject);

这样一来,您就不会有多余的项目,ArrayList例如,如果要添加项目,例如,

list = new ArrayList(mItems.size());    
list.add(position, SomeObject);

不会仅覆盖位置中的现有项,而是将现有项向右移动一位-因此,您拥有一个ArrayList的索引数是原来的两倍。


0

您应该设置而不是添加来替换索引中的现有值。

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

列表将包含[object1,object2]

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.