Thêm đối tượng vào ArrayList tại chỉ mục được chỉ định


142

Tôi nghĩ đó là một câu hỏi khá đơn giản, nhưng tôi không thể tìm ra cách làm điều này đúng.

Tôi đã có một danh sách mảng trống:

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

Tôi đã có một số đối tượng tôi muốn thêm và mỗi đối tượng phải ở một vị trí nhất định. Tuy nhiên, điều cần thiết là chúng có thể được thêm vào trong mỗi thứ tự có thể. Khi tôi thử điều này, nó không hoạt động và tôi nhận được IndexOutOfBoundsException:

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

Những gì tôi đã cố gắng là lấp đầy ArrayListvới nullvà sau đó thực hiện ở trên. Nó hoạt động, nhưng tôi nghĩ đó là một giải pháp khủng khiếp. Có một cách khác để làm điều này?


7
Bạn nhận được IndexOutOfBoundException vì danh sách trống và bạn không thể truy cập vào vị trí danh sách không tồn tại ...
Vic

1
Có cách nào để tạo vị trí đó mà không điền vào danh sách với các đối tượng null không? Đối với tôi có vẻ như đó là một giải pháp thực sự kỳ lạ.
J. Maes

1
Tôi không nghĩ vậy ... Nếu bạn cần thêm các đối tượng theo thứ tự ngẫu nhiên, bạn sẽ phải tìm cách khác để làm điều đó .. Ví dụ với một mảng điển hình: 'Object []' và sau đó bạn không nên không phải điền vào nó, chỉ cần khởi tạo
Vic

1
@Maethortje nó không thực sự là một vấn đề kỳ lạ. Tra cứu danh sách thưa thớt, Reference.wolfram.com/mathematica/tutorial/ từ có vẻ là một bài viết tốt. Mặc dù trong Java, một Bản đồ với chỉ mục là khóa có thể là cách tiếp cận dễ dàng nhất.
Biến khổ sở

2
@Pan Ngay cả khi bạn khai báo kích thước .. Nó chỉ không khởi tạo danh sách, nhưng khai báo có bao nhiêu dung lượng bạn muốn dự trữ trong bộ nhớ .. Như tôi thấy, một danh sách là một mảng các phần tử cũng có một con trỏ tới yếu tố tiếp theo. Nếu bạn cố gắng thêm một phần tử vào vị trí thứ ba khi bạn có phần trống thứ hai (hoặc null), bạn không có con trỏ để giúp bạn biết đó là phần tử thứ ba ..: 1-> 2-> 3 là OK, nhưng 1- > * -> 3 ở đây bạn có một vấn đề ...
Vic

Câu trả lời:


209

Bạn có thể làm như thế này:

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

Sau khi bạn thêm object2 vào vị trí 2, nó sẽ di chuyển object3 sang vị trí 3.

Nếu bạn muốn object3 ở vị trí 3 mọi lúc tôi khuyên bạn nên sử dụng HashMap với vị trí là khóa và đối tượng làm giá trị.


3
Một hashmap thực sự sẽ có thể giải quyết vấn đề này. Tôi nghĩ rằng tôi sẽ chọn cái đó vì dường như tôi không thể thêm thứ gì vào vị trí 3 khi không có đối tượng ở vị trí 2.
J. Maes

Câu trả lời ngắn gọn nhưng nhiều nhất. Những người khác đang đi sai đường
Shabbir Dhangot

Một logic xây dựng!
Arsal Imam

31

Bạn có thể sử dụng Mảng đối tượng và chuyển đổi nó thành 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 sẽ là- [1, null, 2, 3, null, null, null, 7, null, null]


2
Một nhược điểm là bạn phải biết kích thước trước.
Daniel Hári

17

Nếu đó là trường hợp thì tại sao bạn không cân nhắc sử dụng Mảng thông thường, hãy khởi tạo dung lượng và đặt các đối tượng vào chỉ mục bạn muốn.

Object[] list = new Object[10];

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

Bạn kích hoạt dung lượng, nhưng không phải kích thước của 'ArrayList'. Kích thước được xác định là số phần tử và khi chỉ mục> kích thước, ngoại lệ xuất hiện ...
Vic

@Vic, lúc đầu tôi đọc sai câu hỏi, nhưng cảm ơn vì tiền boa.
medopal

Tôi đã khởi tạo dung lượng ở mức 10, nhưng tôi vẫn nhận được IndexOutOfBoundExceptopn khi thêm một đối tượng. Tương tự với việc thay đổi công suất với notifyCapacity. Chỉ có điều hoạt động được lấp đầy bằng null vào lúc này ...
J. Maes

@Maethortje Hãy tìm sự khác biệt giữa "kích thước" và "công suất" ... Ngoại lệ xuất hiện khi chỉ số là> kích thước, không phải khi đó là> công suất .....
Vic

Như những người đã đề cập, bạn đang thêm một đối tượng ở chỉ số 3, trong khi kích thước của danh sách vẫn là 1. Điều đó là không thể. Thêm vào chỉ mục cụ thể được cho phép miễn là chỉ mục này nằm trong ranh giới của danh sách, ví dụ: nếu danh sách của bạn có 3 đối tượng, bạn không thể thêm một đối tượng tại chỉ mục 100.
medopal

14

Bạn cũng có thể ghi đè ArrayList để chèn null giữa kích thước của bạn và phần tử bạn muốn thêm.

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);
    }
}

Sau đó, bạn có thể thêm tại bất kỳ điểm nào trong ArrayList. Ví dụ, phương thức chính này:

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));
    }
}   

mang lại kết quả này từ bàn điều khiển:

0: không

1 một

2: hai

3: không

4: không

5: năm


9

Tôi thu hút sự chú ý của bạn vào ArrayList.addtài liệu , trong đó nói rằng nó ném IndexOutOfBoundsException- nếu chỉ mục nằm ngoài phạm vi ( index < 0 || index > size())

Kiểm tra size()danh sách của bạn trước khi bạn gọilist.add(1, object1)


Bạn đúng @Hemal, @Maethortje Tại sao bạn không kiểm tra kích thước của danh sách trước khi bạn thêm phần tử vào danh sách? kiểm tra xem vị trí bạn đang cố thêm có nhỏ hơn kích thước của danh sách không, nếu không thì bạn chỉ có thể làm bình thườnglist.add("element");
Rakesh

1
Theo tôi hiểu, "vấn đề" là thêm phần tử ở vị trí 3 ngay cả khi không có phần tử nào ở vị trí 2 ...
Vic

@Vis đó là một danh sách thưa thớt - xem bình luận của tôi cho câu hỏi.
Biến khổ sở

5

Bạn cần điền các chỉ mục trống bằng null.

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

arraylist.add(position, object);

2
@Maethortje 

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

trong khi cố gắng thêm một phần tử ở vị trí đã chỉ định, bạn đã có IndexOutOfBound, vì vậy danh sách nên có một số phần tử ở vị trí của chúng.

Hãy thử làm theo

/*
  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

*/

Tôi hiểu vấn đề gây ra lỗi của tôi. Có vẻ như tôi phải thêm các đối tượng vào các vị trí tiếp theo trước khi tôi có thể thêm một đối tượng vào vị trí đó. Khoảnh khắc tôi đang thêm, tôi không xử lý tất cả các đối tượng tôi muốn thêm. Bạn có nghĩ rằng thêm các đối tượng null là một giải pháp thích hợp sau đó?
J. Maes

@Maethortje Sẽ không công bằng khi làm điều này, vì nó chỉ là một vụ hack :)
Sankalp

bạn cần loại bỏ các trích dẫn mẫu mã từ đoạn đầu tiên.
Jalal Sordo

2

Làm thế nào về whilevòng lặp nhỏ này như là một giải pháp?

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

Đây là một giải pháp có thể:

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

1

Tôi nghĩ rằng giải pháp từ medopal là những gì bạn đang tìm kiếm.

Nhưng chỉ có một giải pháp thay thế khác là sử dụng HashMap và sử dụng khóa (Integer) để lưu trữ các vị trí.

Bằng cách này, ban đầu bạn sẽ không cần phải điền vào nó bằng null, chỉ cần dán vị trí và đối tượng trong bản đồ khi bạn đi cùng. Bạn có thể viết một vài dòng ở cuối để chuyển đổi nó thành Danh sách nếu bạn cần nó theo cách đó.


Không phải TreeMap là tốt hơn kể từ khi được đặt hàng bởi các phím?
Daniel Hári

1

Giả sử bạn muốn thêm một mục tại một vị trí, thì kích thước danh sách phải nhiều hơn vị trí.

add(2, item): cú pháp này có nghĩa là, di chuyển mục cũ ở vị trí 2 sang chỉ mục tiếp theo và thêm mục ở vị trí thứ 2.

Nếu không có mục nào ở vị trí thứ 2, thì điều này sẽ không hoạt động, Nó sẽ ném một ngoại lệ.

Điều đó có nghĩa là nếu bạn muốn thêm một cái gì đó vàoposition 2,

kích thước danh sách của bạn phải ít nhất là (2 + 1) =3,để các mặt hàng có sẵn tại0,1,2 Position.

theo cách đó, đảm bảo rằng vị trí 2 được truy cập an toàn và sẽ không có ngoại lệ.


2
Tôi chỉ đi ngang qua khi tôi thông báo câu trả lời của bạn ... thực ra, chỉ mục phải thấp hơn hoặc bằng với độ dài thực của danh sách tại thời điểm chúng tôi đang chèn mục mới. shoutample: kích thước danh sách là 2: thêm vào chỉ mục 2 sẽ hoạt động. thêm vào chỉ số 3 sẽ ném một ngoại lệ. (Nó đã được thử nghiệm)
Houssem Chlegou

0

Nếu bạn đang sử dụng hương vị Android của Java, tôi có thể đề xuất sử dụng SpzzyArray . Đó là ánh xạ hiệu quả bộ nhớ của các số nguyên đến các đối tượng và dễ lặp lại hơn so với Bản đồ


0

Bit muộn nhưng hy vọng vẫn có thể hữu ích cho ai đó.

2 bước để thêm các mục vào một vị trí cụ thể trong một ArrayList

  1. add null mục vào một chỉ mục cụ thể trong một ArrayList
  2. Sau đó, setcác vị trí như và khi được yêu cầu.

        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);

Bằng cách này, bạn không có các mục dư thừa, ArrayListtức là nếu bạn muốn thêm các mục như,

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

Điều này sẽ không ghi đè lên các mục hiện có ở vị trí đơn thuần, chuyển các mục hiện có sang bên phải một - vì vậy bạn có một ArrayList với số lần chỉ ra gấp đôi.


0

Bạn nên đặt thay vì thêm để thay thế giá trị hiện tại tại chỉ mục.

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

Danh sách sẽ chứa [object1, object2]

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.