Soru Diziden ArrayList oluştur


Benim gibi başlatılan bir dizi var:

Element[] array = {new Element(1), new Element(2), new Element(3)};

Bu diziyi ArrayList sınıfının bir nesnesine dönüştürmek istiyorum.

ArrayList<Element> arraylist = ???;

2967
2017-10-01 14:38


Menşei


Java9 -> List <String> list = List.of (“Merhaba”, “Dünya”, “from”, “Java”); - MarekM
@MarekM Bu cevap yanlış; ArrayList. Poster bunun için özel olarak sordu. - Tobias Weimer
Liste arayüzünü kullanmıyordu, çünkü en iyi uygulama. Ama burada isterseniz - yeni ArrayList <> (List.of (“Merhaba”, “Dünya”, “from”, “Java”)); - MarekM
Buradaki nokta, arayüzün kullanımı ile ilgili değildir, konu, çözümünüzde iade edilen listenin değiştirilemez olmasıdır. Bu bir problem olabilir ve bir ArrayList için neden sordu? - Tobias Weimer


Cevaplar:


new ArrayList<>(Arrays.asList(array))

3971
2017-10-01 14:39



Evet. Ve (en yaygın) durumda, sadece bir liste istediğiniz yerde new ArrayList çağrı da gereksizdir. - Calum
@Luron - sadece kullan List<ClassName> list = Arrays.asList(array) - Pool
@Calum ve @Pool - Alex Miller'ın cevabında aşağıda belirtildiği gibi, Arrays.asList(array) onu yeni haline geçirmeden ArrayList nesne listenin boyutunu düzeltir. Kullanmanın en yaygın nedenlerinden biri ArrayList boyutlarını dinamik olarak değiştirebilmeniz ve öneriniz bunu engelleyecektir. - Code Jockey
Arrays.asList () korkunç bir işlev ve asla dönüş değerini asla kullanmamalısınız. Liste şablonunu kırar, bu nedenle her zaman, burada gereksiz şekilde görünse bile, burada belirtilen formda kullanın. İyi cevap. - Adam
@Adam Lütfen java.util.List için javadoc çalışın. Ekleme sözleşmesi, bir UnsupportedOperationException atamasına olanak tanır. docs.oracle.com/javase/7/docs/api/java/util/...  Kuşkusuz, nesneye yönelik bir perspektiften bakıldığında, bir koleksiyonun kullanılması için somut uygulamayı bilmek zorunda olduğunuz çoğu zaman çok da iyi değil - bu, çerçeveyi basit tutmak için pragmatik bir tasarım seçeneğiydi. - lbalazscs


Verilen:

Element[] array = new Element[] { new Element(1), new Element(2), new Element(3) };

En basit cevap yapmak:

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

Bu iyi çalışacaktır. Ama bazı uyarılar:

  1. AsList’ten dönen liste sabit boyut. Bu nedenle, kodunuzda döndürülen listeden öğeler ekleyebilmeniz veya çıkartabilmek istiyorsanız, bunu yeni bir kutuya sarmanız gerekir. ArrayList. Aksi takdirde bir UnsupportedOperationException.
  2. Listeden döndü asList() orijinal dizi tarafından desteklenmektedir. Orijinal diziyi değiştirirseniz, liste de değiştirilecektir. Bu şaşırtıcı olabilir.

775
2017-10-01 15:39



Her iki operasyonun zaman karmaşıklığı nedir? Açık arraylist inşaatı kullanmaksızın ve kullanmadan demek istiyorum. - damned
Arrays.asList () sadece varolan diziyi sararken bir ArrayList oluşturur, böylece O (1). - Alex Miller
Yeni bir ArrayList () 'de sarmak, sabit boyutlu listenin tüm elemanlarının yinelenmesine ve yeni ArrayList'e eklenmesine neden olacak ve böylece O (n). - Alex Miller
asList () tarafından döndürülen listenin uygulanması, UnsupportedOperationException öğesini açıklayan bir çok List yöntemini (add (), remove (), clear (), vb ...) uygulamamaktadır. kesinlikle bir uyarı ... - sethro
Soru "ArrayList sınıfının bir nesnesi" için sorulduğunda, atıfta bulunulan dersi kabul etmenin makul olduğunu düşünüyorum. java.util.ArrayList. Arrays.asList aslında döndürür java.util.Arrays.ArrayList hangi bir değil instanceof diğer sınıf. Bu yüzden üçüncü bir uyarı, eğer bunu gerektiren bir bağlamda kullanmaya çalışırsanız işe yaramayacaktır. - Dave L.


(eski iplik, ama Guava ya da diğer libs ve diğer bazı ayrıntıları hiçbiri gibi sadece 2 sent)

Yapabilirseniz, Guava'yı Kullan

Bu shenaniganları büyük ölçüde basitleştiren Guava yolunu işaret etmeye değer:

kullanım

Ölümsüz bir liste için

Kullan ImmutableList sınıf ve onun of() ve copyOf() fabrika yöntemleri (elementler boş olamaz):

List<String> il = ImmutableList.of("string", "elements");  // from varargs
List<String> il = ImmutableList.copyOf(aStringArray);      // from array

Bir Değişebilir Liste İçin

Kullan Lists sınıf ve onun newArrayList() fabrika yöntemleri:

List<String> l1 = Lists.newArrayList(anotherListOrCollection);    // from collection
List<String> l2 = Lists.newArrayList(aStringArray);               // from array
List<String> l3 = Lists.newArrayList("or", "string", "elements"); // from varargs

Lütfen diğer sınıflardaki diğer veri yapıları için benzer yöntemleri de unutmayın, örneğin Sets.

Neden Guava?

Ana cazibe, Guava'nın kullanımı gibi, tür güvenliği için jenerikler nedeniyle dağınıklığı azaltmak olabilir. fabrika yöntemleri türlerin çoğu zaman çıkmasına izin verin. Ancak, bu argüman Java 7 yeni elmas operatörü ile geldiğinden beri daha az su tutar.

Ancak tek sebep bu değil (ve Java 7 her yerde değil): kısa yazım sözdizimi de çok kullanışlıdır ve yukarıda görüldüğü gibi, başlatma başlatıcıları daha anlamlı bir kod yazmayı sağlar. Mevcut Java Koleksiyonları ile 2'yi alan tek bir Guava çağrısında bulunuyorsunuz.


Eğer yapamazsan ...

Ölümsüz bir liste için

JDK'ları kullan Arrays sınıf ve onun asList() ile sarılmış fabrika yöntemi Collections.unmodifiableList():

List<String> l1 = Collections.unmodifiableList(Arrays.asList(anArrayOfElements));
List<String> l2 = Collections.unmodifiableList(Arrays.asList("element1", "element2"));

İçin döndürülen türü unutmayın asList() bir List beton kullanarak ArrayList uygulama, ama o değil  java.util.ArrayList. Bu, bir öykünen bir iç tiptir ArrayList ancak aslında geçirilen diziyi doğrudan referanslar ve "yazım" (dizilerdeki değişiklikler yansıtılır) yapar.

Bazıları aracılığıyla değişiklik yapılmasını yasaklar List Basit bir şekilde genişleterek API'nın yöntemleri AbstractList (böylece, eleman ekleme veya çıkarma desteklenmez), ancak set() öğeleri geçersiz kılmak. Böylece bu liste gerçekten değişmez ve asList() ile sarılmalıdır Collections.unmodifiableList().

Değiştirilebilir bir listeye ihtiyacınız varsa, sonraki adıma bakın.

Bir Değişebilir Liste İçin

Yukarıdaki ile aynı, ancak gerçek ile sarılmış java.util.ArrayList:

List<String> l1  = new ArrayList<String>(Arrays.asList(array));    // Java 1.5 to 1.6
List<String> l1b = new ArrayList<>(Arrays.asList(array));          // Java 1.7+
List<String> l2  = new ArrayList<String>(Arrays.asList("a", "b")); // Java 1.5 to 1.6
List<String> l2b = new ArrayList<>(Arrays.asList("a", "b"));       // Java 1.7+

Eğitim Amaçlı İçin: Good ol 'Manual Way

// for Java 1.5+
static <T> List<T> arrayToList(final T[] array) {
  final List<T> l = new ArrayList<T>(array.length);

  for (final T s : array) {
    l.add(s);
  }
  return (l);
}

// for Java < 1.5 (no generics, no compile-time type-safety, boo!)
static List arrayToList(final Object[] array) {
  final List l = new ArrayList(array.length);

  for (int i = 0; i < array.length; i++) {
    l.add(array[i]);
  }
  return (l);
}

295
2017-11-16 17:16



+1 Ama unutmayın ki List tarafından döndürülen Arrays.asList hala yapabilirsiniz ki hala yapabilirsiniz set elemanlar - sadece yeniden boyutlandırılabilir değil. Guava olmadan değişmeyen listeler için Collections.unmodifiableList. - Paul Bellora
@haylem Senin bölümün Eğitim Amaçlı İçin: Good ol 'Manual Way, sizin arrayToList Java 1.5+ için yanlıştır. Listeleri listeliyorsunuz Stringve jenerik parametre türünü kullanmak yerine verilen diziden dizeleri almaya çalışmak, T. Bunun dışında, iyi bir cevap ve manuel yol da dahil olmak üzere tek kişi olmak için +1. - afsantos


Bu soru oldukça eski olduğundan, kimsenin henüz en basit formu önermediği beni şaşırtıyor:

List<Element> arraylist = Arrays.asList(new Element(1), new Element(2), new Element(3));

Java 5'ten itibaren Arrays.asList() bir varargs parametresi alır ve diziyi açıkça oluşturmak zorunda kalmazsınız.


203
2018-06-22 11:30



Özellikle, List<String> a = Arrays.asList("first","second","third") - 18446744073709551615


new ArrayList<T>(Arrays.asList(myArray));

Emin olun myArray aynı tür T. Bir oluşturmaya çalışırsanız bir derleyici hatası alırsınız. List<Integer>bir dizi int, Örneğin.


172
2017-10-01 14:40





Başka bir yol (esas olarak eşdeğer olmasına rağmen new ArrayList(Arrays.asList(array)) çözüm performansı-bilge:

Collections.addAll(arraylist, array);

77
2018-04-03 23:20





Muhtemelen bir Listeye ihtiyacınız var, bir ArrayList değil. Bu durumda sadece yapabilirsiniz:

List<Element> arraylist = Arrays.asList(array);

62
2017-10-01 14:45



Bu, orijinal giriş dizisi tarafından desteklenecektir, bu yüzden (muhtemelen) yeni bir ArrayList'e sarmak istersiniz. - Bill the Lizard
Bu çözüme dikkat edin. Eğer bakarsanız, Diziler gerçek bir java.util.ArrayList döndürmez. Gerekli yöntemleri uygulayan bir iç sınıf döndürüyor, ancak listedeki notları değiştiremezsiniz. Bir dizi etrafında sadece bir sarıcı var. - Mikezx6r
Liste <Öğe> öğesini bir ArrayList <Öğesine> atayabilirsiniz - monksy
@ Mikezx6r: küçük düzeltme: Sabit boyutlu bir liste. Listenin elemanlarını değiştirebilirsiniz (set yöntem), listenin boyutunu değiştiremezsiniz ( addveya remove elementler)! - Carlos Heuberger
Evet, uyarı ile listeyle ne yapmak istediğinize bağlı. OP'nin sadece elemanlar üzerinden yineleme yapmak istemesi durumunda, dizinin hiç dönüştürülmemesi gerektiği dikkate alınmalıdır. - PaulMurrayCbr


Java 9

İçinde Java 9, kullanabilirsiniz List.of oluşturmak için statik fabrika metodu List değişmezi. Aşağıdaki gibi bir şey:

List<Element> elements = List.of(new Element(1), new Element(2), new Element(3));

Bu bir geri dönecekti değişmez üç öğe içeren liste. Eğer istersen değişken listeye ArrayList yapıcı:

new ArrayList<>(List.of(// elements vararg))

JEP 269: Koleksiyonlar için Kullanışlı Fabrika Yöntemleri

JEP 269 için bazı kolaylık fabrika yöntemleri sağlar Java Koleksiyonları API. Bu değişmez statik fabrika yöntemleri List, Set, ve Map Java 9 ve sonrası arayüzleri.


59
2018-04-17 16:58





Başka bir güncelleme, neredeyse sona eren yıl 2014, bunu Java 8 ile de yapabilirsiniz:

ArrayList<Element> arrayList = Stream.of(myArray).collect(Collectors.toCollection(ArrayList::new));

Birkaç karakter kaydedilecekti, eğer bu sadece bir List 

List<Element> list = Stream.of(myArray).collect(Collectors.toList());

54
2017-11-25 20:48



Muhtemelen uygulamaya bağımlı olmak en iyisi değil, ama Collectors.toList() aslında bir döner ArrayList. - bcsb1001
Stream.of (...) yanlış kullanımı; Bu tek bir eleman akışı oluşturacaktır. Bunun yerine Arrays.stream kullanın - Patrick Parker
Öyle düşünmüyorum, 2 seçenek geçerli, ancak Arrays.stream biraz 'daha iyi' çünkü sabit boyutlu, 'start', 'end' args ile aşırı yükleme yöntemini kullanarak oluşturabilirsiniz. Ayrıca bakınız: stackoverflow.com/a/27888447/2619091 - whyem


Diziyi bir ArrayList'e dönüştürmek için geliştiriciler genellikle bunu yapar:

List<String> list = Arrays.asList(arr);// this is wrong way..

Arrays.asList() bir ArrayList döndürür private static class inside Arraysjava.util.ArrayList sınıfı değil. The java.util.Arrays.ArrayList sınıf var set(), get(), contains() yöntemleri, ancak öğeleri eklemek için herhangi bir yöntemi yoktur, bu yüzden boyutu sabittir. Gerçek bir ArrayList oluşturmak için şunları yapmalısınız:

ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr));

ArrayList kurucusu bir Koleksiyon tipi, aynı zamanda için süper bir türüdür java.util.Arrays.ArrayList


47
2018-06-25 07:20



Sadece ihtiyacın varsa yanlış yol değil Listve gerek yok ArrayListAslında çoğu zaman bunu yapmıyorsun. Geliştiricilerin çoğu zaman bir ArrayList alışkanlıktan yoksun, ihtiyaçtan daha fazlası. - Christoffer Hammarström
@ ChristofferHammarström ile katılıyorum, her ikisi de geçerlidir List<String> list = Arrays.asList(arr); oluşturmak için kullanılır List ve ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr)); oluşturmak için kullanılır ArrayList. Muhtemelen @Nepster sadece bir özü yapıştırdı programcreek.com/2013/04/... - Nikhil Katre


Eğer kullanırsan :

new ArrayList<T>(Arrays.asList(myArray));

sen Mayıs ayı yaratmak ve doldurun iki liste! İki kez büyük bir listeyi doldurmak, yapmak istemediğiniz şeydir, çünkü başka bir şey yaratacaktır. Object[] Her defasında kapasitenin genişletilmesi gerekir.

Neyse ki JDK uygulaması hızlı ve Arrays.asList(a[]) çok iyi bitti. Object [] verilerinin doğrudan diziye işaret ettiği Arrays.ArrayList adında bir ArrayList türü oluşturur.

// in Arrays
@SafeVarargs
public static <T> List<T> asList(T... a) {
    return new ArrayList<>(a);
}
//still in Arrays, creating a private unseen class
private static class ArrayList<E>

    private final E[] a;    
    ArrayList(E[] array) {
        a = array; // you point to the previous array
    }
    ....
}

Tehlikeli tarafı İlk diziyi değiştirirseniz, Listeyi değiştirirsiniz! Bunu istediğine emin misin? Belki evet belki hayır.

Değilse, en anlaşılabilir yol bunu yapmaktır:

ArrayList<Element> list = new ArrayList<Element>(myArray.length); // you know the initial capacity
for (Element element : myArray) {
    list.add(element);
}

Ya da @glglgl dediği gibi, başka bir bağımsız ArrayList yaratabilirsiniz:

new ArrayList<T>(Arrays.asList(myArray));

Kullanmayı seviyorum Collections, Arraysveya Guava. Fakat eğer uymuyorsa veya hissetmiyorsanız, onun yerine başka bir inelegant çizgisi yazın.


30
2018-01-18 13:01



Cevabın sonunda döngü arasındaki temel farkı göremiyorum ve new ArrayList<T>(Arrays.asList(myArray)); kullanmaktan vazgeçtiğiniz bölüm. Her ikisi de aynı şeyi yapıyor ve aynı karmaşıklığa sahip. - glglgl
Koleksiyonlar biri dizinin başında bir işaretçi oluşturur. Döngüüm çok sayıda işaretçi oluşturuyor: her dizi üyesi için bir tane. Öyleyse eğer orijinal dizi değişirse, avcılarım hala eski değerlere yöneliyorlar. - Nicolas Zozol
new ArrayList<T>(Arrays.asList(myArray)); aynı, kopyaları asList bir ArrayList... - glglgl