Java'da bir dizi LinkedList oluşturulamıyor…?


102

Bir matrisin değerlerini depolamak için dizi kullanması gereken seyrek bir matris sınıfı üzerinde çalışıyorum LinkedList. Dizinin her bir öğesi (yani her biri LinkedList) matrisin bir satırını temsil eder. Ve LinkedListdizideki her öğe bir sütunu ve depolanan değeri temsil eder.

Sınıfımda, dizinin şu şekilde bir bildirimi var:

private LinkedList<IntegerNode>[] myMatrix;

Ve SparseMatrixiçin kurucumda şunu tanımlamaya çalışıyorum:

myMatrix = new LinkedList<IntegerNode>[numRows];

Sonunda aldığım hata

Genel bir dizi oluşturulamaz LinkedList<IntegerNode>.

Yani, bununla ilgili iki sorunum var:

  1. Neyi yanlış yapıyorum ve
  2. Oluşturulamıyorsa, dizi için bildirimde tür neden kabul edilebilir?

IntegerNodebenim oluşturduğum bir sınıf. Ve tüm sınıf dosyalarım bir arada paketlenmiştir.

Yanıtlar:


64

Genel dizi oluşturmayı kullanamazsınız. Bu java jeneriklerinin bir kusuru / özelliği.

Uyarısız yollar şunlardır:

  1. Liste Dizisi yerine Liste Listesini Kullanma:

    List< List<IntegerNode>> nodeLists = new LinkedList< List< IntegerNode >>();
  2. Liste Dizisi için özel sınıfı bildirmek:

    class IntegerNodeList {
        private final List< IntegerNode > nodes;
    }

19
İkinci çözüme daha iyi bir alternatif class IntegerNodeList extends List<IntegerNode> {}
şudur

Bu uygulama aşırı derecede yavaş. [1000] [2000] öğesini (nodeLists.get (1000) .get (2000)) almak LinkedList'in 3000 kez yinelenmesini sağlayacaktır! Herhangi biri dizine ekliyorsa LinkedList'ten kaçının. ArrayList daha hızlı indeksleyecektir, ancak Fredrik'in çözümü genel olarak daha iyidir.
Steve Zobell

142

Bazı nedenlerden dolayı türü atmanız ve şu şekilde beyanda bulunmanız gerekir:

myMatrix = (LinkedList<IntegerNode>[]) new LinkedList<?>[numRows];

Benzer bir sorunu araştırdım ve yukarıdaki dökümün, koleksiyon çerçevesinin her yerinde kullanılan çok yaygın bir 'hack' olduğunu okudum.
luke

15
IMO, seçilen cevap bu olmalı. Deney yapmadım, ancak Sergey'in # 2 yönteminin oldukça fazla ek yük oluşturduğuna dair içimden bir his var; ve ben # 1'in yaptığı POZİTİF. Bir liste, burada detaylandırmayacağım birkaç yönden bir dizi kadar verimli değildir, ancak dizilere kıyasla listeleri kullanırken deneyler yaptım ve büyük yavaşlamalar gördüm. Kendi dizilerinizi yönetmek ve onları yeniden tahsis etmek, bir Listeye bir şeyler eklemekten daha hızlıdır.
Ricket


4
Yine de "Tip güvenliği: kontrol edilmemiş döküm" uyarısı alıyorum. Bob'un çözümü bana en temiz görünüyor.
Marco Lackovic

3
JDK 7'de yukarıdakiler bir ham tip uyarısı verir. Bu, sınırsız <?> Türü kullanılarak düzeltilebilir, ancak yine de denetlenmemiş bir uyarı alırsınız (bastırılabilir). ör. <br> <code> myMatrix = (LinkedList <IntegerNode> []) new LinkedList <?> [numRows]; </code>
Neon

5

Söz dizimi sorunlarının yanı sıra, bir matrisi temsil etmek için bir dizi ve bağlantılı bir liste kullanmak bana garip geliyor. Matrisin rastgele hücrelerine erişebilmek için, büyük olasılıkla gerçek bir dizi veya en azından bir ArrayListsatırları tutmak isteyeceksiniz , çünkü LinkedListtüm listeyi ilk öğeden herhangi bir belirli öğeye, bir O(n)işlemden çok çabuk O(1)ileArrayList gerçek bir dizi .

Bu matrisin seyrek olduğundan bahsettiğiniz için, yine de, verileri depolamanın belki de daha iyi bir yolu, ilk haritadaki bir anahtarın bir satır indeksini temsil ettiği ve değeri, anahtarları bir sütun indeksi olan bir satır haritası olduğu bir harita haritasıdır. , değer, IntegerNode sınıfınızdır. Böylece:

private Map<Integer, Map<Integer, IntegerNode>> myMatrix = new HashMap<Integer, Map<Integer, IntegerNode>>();

// access a matrix cell:
int rowIdx = 100;
int colIdx = 30;
Map<Integer, IntegerNode> row = myMatrix.get(rowIdx); // if null, create and add to matrix
IntegerNode node = row.get(colIdx); // possibly null

Matrisi satır satır geçebilmeniz gerekiyorsa, satır eşlem tipini a yapabilirsiniz TreeMapve sütunları indeks sırasına göre geçiş yapmak için de aynıdır, ancak bu durumlara ihtiyacınız yoksa HashMapbundan daha hızlıdır TreeMap. Elbette, rastgele bir hücre elde etmek ve ayarlamak için yardımcı yöntemler, ayarlanmamış boş değerleri ele almak yararlı olacaktır.


4
class IntegerNodeList extends LinkedList<IntegerNode> {}

IntegerNodeList[] myMatrix = new IntegerNodeList[numRows]; 

LinkedList için jenerikleri kaçırdınız.
Peter Wippermann

3

myMatrix = (LinkedList<IntegerNode>[]) new LinkedList[numRows];

bu şekilde kullanmak işe yarar ama yine de sizi kötü bir uyarıyla bırakır:

"Tür güvenliği: List [] türünün ifadesi, denetlenmemiş dönüştürme gerektiriyor .."

Liste Dizisi için özel bir sınıf bildirmek:

class IntegerNodeList { private final List< IntegerNode > nodes; }

uyarıdan kaçınmak için akıllıca bir fikir. belki biraz daha güzel, bunun için bir arayüz kullanmaktır:

public interface IntegerNodeList extends List<IntegerNode> {}

sonra

List<IntegerNode>[] myMatrix = new IntegerNodeList[numRows];

uyarı olmadan derler.

çok kötü görünmüyor, değil mi?


IntegerNodeList: Bunu hangi sınıfla kullanırsınız? Örneğin, ona bir ArrayList <IntegerNode> atayamazsınız. ArrayList'i de uzatmanız gerekecek ...
Hans-Peter Störr 01.10

Dizinin başlatılmasının dışında IntegerNodeList arayüzünü kullanmaya gerek yoktur: List <IntegerNode> [] myMatrix = new IntegerNodeList [5]; for (int i = 0; i <myMatrix.length; i ++) {myMatrix [i] = new ArrayList <IntegerNode> (); }
user306708

1
List<IntegerNode>[] myMatrix = new IntegerNodeList[numRows];Bunun ince ama önemli bir sorunu var. Sen olabilir ancak koymak IntegerNodeListdizide. myMatrix[i] = new ArrayList<IntegerNode>();atacak ArrayStoreException.
Radiodef

2
List<String>[] lst = new List[2];
lst[0] = new LinkedList<String>();
lst[1] = new LinkedList<String>();

Uyarı yok. NetBeans 6.9.1, jdk1.6.0_24


1
Doğru uyarı yok ama Oracle'ın Java SE 6 Güncellemesi 32 ile "Liste türü genel değil; <String> bağımsız değişkenleriyle parametreleştirilemez" derleme hatası alıyorum. <String> bağımsız değişkeninin kaldırılması, başka bir "Tür uyuşmazlığı: LinkedList <String> 'den Listeye dönüştürülemiyor" hatası oluşturur.
Marco Lackovic


0

Aşağıdakileri yaparsam söz konusu hata mesajını alıyorum

LinkedList<Node>[] matrix = new LinkedList<Node>[5];

Ancak beyandaki liste türünü kaldırırsam, istenen işlevselliğe sahip görünüyor.

LinkedList<Node>[] matrix = new LinkedList[5];

Bu iki beyan benim farkında olmadığım bir şekilde büyük ölçüde farklı mı?

DÜZENLE

Ah, sanırım şimdi bu sorunla karşılaştım.

Matris üzerinde yineleme yapmak ve listeleri bir for-döngüde başlatmak işe yarıyor gibi görünüyor. Sunulan diğer çözümlerden bazıları kadar ideal olmasa da.

for(int i=0; i < matrix.length; i++){

    matrix[i] = new LinkedList<>();
}

0

Bir dizi Listeye ihtiyacınız var, bir alternatif denemektir:

private IntegerNode[] node_array = new IntegerNode[sizeOfYourChoice];

Daha sonra node_array[i]bir ArrayList<IntegerNode>veya daha sonra baş (ilk) düğümünüLinkedList<IntegerNode> (favori liste uygulamanız ne olursa olsun .

Bu tasarım kapsamında, rastgele erişim yöntemini kaybedersiniz list.get(index) , ancak daha sonra, güvenli dizideki baş / ilk düğüm deposu ile başlayarak listeyi yine de gezebilirsiniz.

Bu, kullanım durumunuza bağlı olarak kabul edilebilir bir tasarım seçeneği olabilir. Örneğin, bu tasarımı grafiğin bitişik bir listesini temsil etmek için kullanıyorum, çoğu kullanım durumunda, listedeki bazı köşelere rastgele erişim yerine belirli bir köşe için yine de bitişik listeyi geçmeyi gerektiriyor.

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.