เพิ่มวัตถุไปยัง ArrayList ที่ดัชนีที่ระบุ


142

ฉันคิดว่ามันเป็นคำถามที่ค่อนข้างง่าย แต่ฉันไม่สามารถหาวิธีที่จะทำอย่างถูกต้อง

ฉันมี arraylist ที่ว่างเปล่า:

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

ฉันมีบางอย่างที่ฉันต้องการเพิ่มและแต่ละวัตถุจะต้องอยู่ในตำแหน่งที่แน่นอน มีความจำเป็น แต่สามารถเพิ่มได้ในแต่ละคำสั่งที่เป็นไปได้ เมื่อฉันลองทำสิ่งนี้มันใช้ไม่ได้และฉันได้รับIndexOutOfBoundsException:

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

สิ่งที่ฉันได้ลองทำคือเติมArrayListด้วยnullแล้วทำตามข้างบน มันใช้งานได้ แต่ฉันคิดว่ามันเป็นทางออกที่น่ากลัว มีวิธีอื่นในการทำเช่นนี้หรือไม่?


7
คุณจะได้รับ IndexOutOfBoundsException เพราะรายการเป็นที่ว่างเปล่าและคุณไม่สามารถเข้าถึงตำแหน่งรายการที่ไม่ได้อยู่ ...
วิก

1
มีวิธีการสร้างตำแหน่งนั้นโดยไม่ต้องเติมรายการด้วยวัตถุ null หรือไม่? สำหรับฉันดูเหมือนว่ามันเป็นทางออกที่แปลกจริงๆ
J. Maes

1
ฉันไม่คิดอย่างนั้น ... หากคุณต้องการเพิ่มวัตถุในลำดับแบบสุ่มคุณจะต้องมองหาวิธีอื่นในการทำมันตัวอย่างเช่นอาร์เรย์ทั่วไป: 'Object []' และคุณไม่ควร ไม่จำเป็นต้องกรอกข้อมูลเพียงแค่เริ่มต้น
Vic

1
@Maethortje มันไม่ได้เป็นปัญหาที่แปลกจริงๆ ค้นหารายการที่เบาบางReference.wolfram.com/mathematica/tutorial/…ดูเหมือนบทความที่ดี ใน Java นั้นแผนที่ที่มีดัชนีเป็นกุญแจอาจเป็นวิธีที่ง่ายที่สุด
ผันแปรได้

2
@Pan ถึงแม้ว่าคุณจะประกาศขนาด .. มันไม่ได้เริ่มต้นรายการ แต่ประกาศว่าคุณต้องการจองพื้นที่ในหน่วยความจำเท่าไหร่ .. เท่าที่ฉันเห็นรายการมีอาร์เรย์ขององค์ประกอบที่มีตัวชี้ไปยัง องค์ประกอบถัดไป หากคุณพยายามที่จะเพิ่มองค์ประกอบเข้าไปในตำแหน่งที่สามเมื่อคุณมีที่ว่างที่สอง (หรือ null) คุณไม่มีตัวชี้ที่จะช่วยให้คุณรู้ว่ามันเป็นองค์ประกอบที่สาม .. : 1-> 2-> 3 ก็โอเค แต่ 1- > * -> 3 ที่นี่คุณมีปัญหา ...
Vic

คำตอบ:


209

คุณสามารถทำได้เช่นนี้:

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

หลังจากคุณเพิ่ม object2 ไปยังตำแหน่ง 2 แล้วมันจะย้าย object3 ไปยังตำแหน่ง 3

หากคุณต้องการให้ object3 อยู่ที่ position3 ตลอดเวลาฉันขอแนะนำให้คุณใช้ HashMap ที่มีตำแหน่งเป็นคีย์และวัตถุเป็นค่า


3
hashmap จะสามารถแก้ปัญหานี้ได้อย่างแน่นอน ฉันคิดว่าฉันจะไปเพราะนั่นดูเหมือนจะไม่สามารถเพิ่มบางสิ่งบางอย่างที่ตำแหน่ง 3 เมื่อไม่มีวัตถุที่ตำแหน่ง 2
เจ. Maes

สั้น แต่คำตอบส่วนใหญ่ คนอื่นผิดทาง
ชาบับ Dhangot

ตรรกะที่สร้างสรรค์!
Arsal Imam

31

คุณสามารถใช้ Array of objects และแปลงเป็น 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
ข้อเสียเปรียบอย่างหนึ่งคือคุณต้องรู้ขนาดล่วงหน้า
Daniel Hári

17

ถ้าเป็นเช่นนั้นทำไมคุณไม่ลองใช้ Array ปกติให้เริ่มต้นความจุแล้ววางวัตถุที่ดัชนีที่คุณต้องการ

Object[] list = new Object[10];

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

คุณไม่สามารถเพิ่มความจุได้ แต่ไม่ใช่ขนาดของ 'ArrayList' ขนาดถูกกำหนดให้เป็นจำนวนขององค์ประกอบและเมื่อดัชนี> ขนาดยกเว้นมา ...
วิก

@Vic ฉันอ่านคำถามผิดในตอนแรก แต่ขอบคุณสำหรับเคล็ดลับ
medopal

ฉันเริ่มต้นความจุที่ 10 แต่ฉันยังคงได้รับ IndexOutOfBoundsExceptopn เมื่อเพิ่มวัตถุ เช่นเดียวกันกับการเปลี่ยนกำลังการผลิตที่มีความมั่นใจความจุ สิ่งเดียวที่ใช้งานได้จะเต็มไปด้วยโมฆะในขณะนี้ ...
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: หนึ่ง

2: สอง

3: null

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 ที่เป็นรายการที่กระจัดกระจาย - ดูความคิดเห็นของฉันกับคำถาม
ผันแปรได้

5

คุณต้องเติมดัชนีว่างเปล่าด้วยค่า 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 

ในขณะที่พยายามเพิ่มองค์ประกอบในตำแหน่งที่ระบุคุณจะได้รับ 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 มันเป็นนิสัยเป็นธรรมมากที่จะทำเช่นนี้เป็นเพียงแค่สับมัน :)
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)


1

ฉันคิดว่าทางออกจาก medopal คือสิ่งที่คุณกำลังมองหา

แต่อีกทางเลือกหนึ่งคือการใช้ HashMap และใช้คีย์ (จำนวนเต็ม) เพื่อจัดเก็บตำแหน่ง

วิธีนี้คุณไม่จำเป็นต้องเติมข้อมูลด้วย nulls และอื่น ๆ ในตอนแรกเพียงแค่ติดตำแหน่งและวัตถุในแผนที่เมื่อคุณไป คุณสามารถเขียนสองสามบรรทัดในตอนท้ายเพื่อแปลงเป็นรายการได้หากคุณต้องการ


TreeMap ดีกว่าตั้งแต่สั่งซื้อโดยใช้กุญแจหรือไม่?
Daniel Hári

1

สมมติว่าคุณต้องการเพิ่มรายการที่ตำแหน่งจากนั้นขนาดรายการจะต้องมากกว่าตำแหน่ง

add(2, item): ไวยากรณ์นี้หมายถึงย้ายรายการเก่าที่ตำแหน่ง 2 ไปยังดัชนีถัดไปและเพิ่มรายการที่ตำแหน่งที่ 2

หากไม่มีรายการในตำแหน่งที่ 2 จะไม่สามารถใช้งานได้มันจะส่งข้อยกเว้น

นั่นหมายความว่าถ้าคุณต้องการที่จะเพิ่มอะไรบางอย่างposition 2,

ขนาดรายการของคุณต้องมีอย่างน้อย(2 + 1) =3,จึงมีรายการอยู่ที่0,1,2 Position.

ด้วยวิธีดังกล่าวทำให้มั่นใจได้ว่าตำแหน่งที่ 2 เข้าถึงได้อย่างปลอดภัยและจะไม่มีข้อยกเว้น


2
ฉันเพิ่งผ่านไปเมื่อฉันแจ้งคำตอบของคุณ ... จริง ๆ แล้วดัชนีต้องน้อยกว่าหรือเท่ากับความยาวจริงของรายการในขณะที่เรากำลังแทรกรายการใหม่ exhample: ขนาดรายการคือ 2: การเพิ่มในดัชนี 2 จะทำงาน การเพิ่มในดัชนี 3 จะทำให้เกิดข้อยกเว้น (ผ่านการทดสอบแล้ว)
Houssem Chlegou

0

หากคุณกำลังใช้รสชาติของ Android Java อาจฉันขอแนะนำให้ใช้SparseArray มันเป็นการแมปที่มีประสิทธิภาพของหน่วยความจำของจำนวนเต็มกับวัตถุและง่ายกว่าในการทำซ้ำมากกว่าแผนที่


0

สายไปหน่อย แต่หวังว่าจะยังคงมีประโยชน์กับใครบางคน

2 ขั้นตอนในการเพิ่มรายการไปยังตำแหน่งเฉพาะใน ArrayList

  1. add รายการ null ไปยังดัชนีเฉพาะใน 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]

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.