ArrayList'e belirtilen dizinde nesne ekle


142

Bence bu oldukça basit bir soru, ama bunu nasıl düzgün bir şekilde yapacağımı anlayamıyorum.

Boş bir dizilim var:

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

Eklemek istediğim bazı nesneler var ve her nesnenin belirli bir konumda olması gerekiyor. Bununla birlikte, her olası sırayla eklenmeleri gereklidir. Bunu denediğimde, işe yaramaz ve bir IndexOutOfBoundsException:

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

Ne ben denedim dolum olduğu ArrayListile nullve daha sonra yukarıdaki yapıyor. Çalışıyor, ama bence korkunç bir çözüm. Bunu yapmanın başka bir yolu var mı?


7
Liste boş olduğundan ve var olmayan bir liste konumuna erişemediğiniz için bir IndexOutOfBoundsException alıyorsunuz ...
Vic

1
Listeyi boş nesnelerle doldurmadan bu konumu oluşturmanın bir yolu var mı? Bana göre bu çok garip bir çözüm gibi görünüyor.
J. Maes

1
Sanmıyorum ... Nesneleri rastgele bir sırayla eklemeniz gerekiyorsa, bunu yapmanın başka bir yolunu aramak zorundasınız .. Örneğin tipik bir dizi ile: 'Nesne []' ve sonra doldurmak zorunda
Vic

1
@Maethortje gerçekten tuhaf bir sorun değil. Seyrek listelere bakın, reference.wolfram.com/mathematica/tutorial/… iyi bir makale gibi görünüyor. Yine de Java'da, anahtar olarak dizini olan bir Harita en kolay yaklaşım olabilir.
Sefil Değişken

2
@Pan Boyutu bildirseniz bile .. Sadece listeyi başlatmaz, ancak bellekte ne kadar yer ayırmak istediğinizi beyan eder .. Gördüğüm gibi, bir liste aynı zamanda sonraki öğe. İkinci boş (veya null) değere sahip olduğunuzda üçüncü konuma bir öğe eklemeye çalışırsanız, üçüncü öğe olduğunu bilmenize yardımcı olacak işaretçiniz yoktur ..: 1-> 2-> 3 tamam, ancak 1- > * -> 3 burada bir sorunun var ...
Vic

Yanıtlar:


209

Bunu şöyle yapabilirsiniz:

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

Nesne2'yi konum 2'ye ekledikten sonra, nesne3'ü konum 3'e taşır.

Object3'ün her zaman position3'te olmasını istiyorsanız, anahtar olarak konum ve değer olarak nesne içeren bir HashMap kullanmanızı öneririm.


3
Bir hashmap gerçekten de bu sorunu çözebilir. Sanırım bunun için gideceğim, çünkü 2. konumda hiçbir nesne olmadığında 3. konuma bir şey ekleyebileceğim gibi görünmüyor
J. Maes

kısa ama çoğu Cevap. Diğerleri sadece yanlış yolda
Shabbir Dhangot

Yapıcı bir mantık!
Arsal İmam

31

Nesnelerin dizisini kullanabilir ve onu ArrayList'e dönüştürebilirsiniz.

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] olacaktır.


2
Bir dezavantajı boyutu önceden bilmek zorunda olmasıdır.
Daniel Hári

17

Bu durumda neden normal bir Dizi kullanmayı düşünmüyorsunuz, kapasiteyi başlatın ve nesneleri istediğiniz dizine koyun.

Object[] list = new Object[10];

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

Kapasiteyi ilklendiriyorsunuz, ancak 'ArrayList'in boyutunu değil. Boyut, eleman sayısı olarak tanımlanır ve dizin> boyut olduğunda istisna gelir ...
Vic

@Vic, ilk başta soruyu yanlış okudum ama bahşiş için teşekkürler.
medopal

Kapasiteyi 10'da başlattım, ancak bir nesne eklerken hala bir IndexOutOfBoundsExceptopn alıyorum. Kapasiteyi changeCapacity ile değiştirmekle aynı. Çalışan tek şey şu anda null ile dolduruyor ...
J. Maes

@Maethortje "boyut" ve "kapasite" arasındaki farkı arayın ... İstisna, dizin> kapasite olduğunda değil, boyut> olduğunda, gelir .....
Vic

Bahsedildiği gibi, listenin boyutu hala 1 iken, dizin 3'e bir nesne ekliyorsunuz. Bu mümkün değil. Bu dizin listenin sınırları içinde olduğu sürece belirli bir dizine eklemeye izin verilir, örneğin listenizde 3 nesne varsa, 100 dizinine bir nesne ekleyemezsiniz.
medopal

14

Ayrıca, boyutunuz ile eklemek istediğiniz öğe arasına boş değerler eklemek için ArrayList öğesini geçersiz kılabilirsiniz.

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

Ardından ArrayList'in herhangi bir noktasına ekleyebilirsiniz. Örneğin, bu ana yöntem:

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

bu sonucu konsoldan verir:

0: sıfır

1 bir

2: iki

3: boş

4: boş

5: beş


9

Dikkatinizi atılan ArrayList.addbelgelere çekiyorum IndexOutOfBoundsException- eğer indeks aralık dışındaysa ( index < 0 || index > size())

size()Aramadan önce listenizi kontrol edinlist.add(1, object1)


Haklısın @Hemal, @Maethortje Öğeyi listeye eklemeden önce neden listenin boyutunu kontrol etmiyorsun? eklemeye çalıştığınız konumun listenin boyutundan küçük olup olmadığını kontrol edin, eğer değilse normal bir işlem yapabilirsinizlist.add("element");
Rakesh

1
Anladığım kadarıyla, "sorun" 2 konumunda bir eleman olmasa bile 3 konumunda eleman eklemek ...
Vic

@ Bu seyrek bir liste - soruya yaptığım yoruma bakın.
Sefil Değişken

5

Boş dizinleri boş değerlerle doldurmanız gerekir.

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 

belirtilen konuma bir öğe eklemeye çalışırken IndexOutOfBound'a sahip olursunuz, bu nedenle listenin bazı öğeleri konumunda olmalıdır.

Lütfen takip etmeyi deneyin

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

*/

Hataya neden olan sorunu anlıyorum. Bu konuma bir nesne ekleyebilmem için, sonraki konumlara nesne eklemem gerekiyor gibi görünüyor. Eklediğim anda, eklemek istediğim tüm nesneleri elden çıkarmıyorum. Boş nesneler eklemenin uygun bir çözüm olduğunu düşünüyor musunuz?
J. Maes

@Maethortje Sadece bir kesmek gibi bunu yapmak çok adil olmayacak :)
Sankalp

kod örneği tırnaklarını ilk paragraftan kaldırmanız gerekir.
Jalal Sordo

2

whileÇözüm olarak bu küçük döngüye ne dersiniz ?

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

Bu olası bir çözümdür:

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

1

Bence medopal'ın çözümü aradığınız şey.

Ancak başka bir alternatif çözüm, bir HashMap kullanmak ve konumları depolamak için anahtarı (Tamsayı) kullanmaktır.

Bu şekilde başlangıçta nulls vb. Bu şekilde ihtiyacınız varsa bir listeye dönüştürmek için sonunda birkaç satır yazabilirsiniz.


TreeMap anahtarlar tarafından sipariş edildiğinden daha iyi değil mi?
Daniel Hári

1

Bir konuma bir öğe eklemek istediğinizi varsayalım, liste boyutu konumdan büyük olmalıdır.

add(2, item): bu sözdizimi, 2. öğedeki eski öğeyi sonraki dizine taşıyın ve öğeyi 2. konuma ekleyin.

2. konumda hiçbir öğe yoksa, bu işe yaramaz, bir istisna atar.

Bu, içine bir şey eklemek istiyorsanızposition 2,

sizin liste boyutu en az olmalıdır (2 + 1) =3,öğeler mevcuttur böylece0,1,2 Position.

bu şekilde pozisyon 2'ye güvenli bir şekilde erişilmesi sağlanır ve istisna olmayacaktır.


2
Sadece cevabınızı bildirdiğimde geçiyorum ... aslında, indeks yeni öğe eklediğimiz anda listenin gerçek uzunluğundan daha düşük veya eşit olmalıdır . exhample: liste boyutu 2: indeks 2'ye eklemek işe yarar. Dizin 3'e eklemek bir istisna atar. (Test edildi)
Houssem Chlegou

0

Java'nın Android lezzetini kullanıyorsanız, bir SparseArray kullanmanızı öneririm . Tamsayıların nesnelerle bellekte daha verimli bir şekilde eşleştirilmesi ve Harita üzerinden daha kolay yinelenmesi


0

Biraz geç ama umarım birileri için hala yararlı olabilir.

Bir öğedeki belirli bir konuma öğe eklemek için 2 adım ArrayList

  1. add bir öğedeki belirli bir dizine boş öğeler ArrayList
  2. Ardından set, gerektiği gibi konumlar.

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

Bu şekilde, ArrayListyani,

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

Bu olurdu değil üzerine yazma teker sağa mevcut olanları değişen, sadece pozisyonda öğeleri mevcut - Birçok indicies iki kat ile bir ArrayList zorunda.


0

Dizindeki mevcut değeri değiştirmek için add yerine ayarlamalısınız.

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

Liste [nesne1, nesne2] içerecektir

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.