Pracuję nad rzadką klasą macierzy, która musi używać tablicy LinkedList
do przechowywania wartości macierzy. Każdy element tablicy (tj. Każdy LinkedList
) reprezentuje wiersz macierzy. Każdy element LinkedList
tablicy reprezentuje kolumnę i przechowywaną wartość.
W mojej klasie mam deklarację tablicy jako:
private LinkedList<IntegerNode>[] myMatrix;
W moim konstruktorze dla programu SparseMatrix
próbuję zdefiniować:
myMatrix = new LinkedList<IntegerNode>[numRows];
Błąd, który otrzymuję, to
Nie można utworzyć ogólnej tablicy
LinkedList<IntegerNode>
.
Mam z tym dwa problemy:
- Co robię źle i
- Dlaczego typ jest dopuszczalny w deklaracji tablicy, jeśli nie można jej utworzyć?
IntegerNode
to klasa, którą stworzyłem. Wszystkie pliki moich zajęć są spakowane razem.
class IntegerNodeList extends List<IntegerNode> {}
Z jakiegoś powodu musisz rzutować typ i zrobić taką deklarację:
źródło
Pomijając problemy ze składnią, wydaje mi się dziwne używanie tablicy i połączonej listy do reprezentowania macierzy. Aby móc uzyskać dostęp do dowolnych komórek macierzy, prawdopodobnie chciałbyś, aby rzeczywista tablica lub przynajmniej
ArrayList
przechowywała wiersze, ponieważLinkedList
musi przejść całą listę od pierwszego elementu do dowolnego konkretnego elementu,O(n)
operacji, w przeciwieństwie do dużo szybciejO(1)
zArrayList
lub rzeczywistą tablicą.Ponieważ wspomniałeś, że ta macierz jest rzadka, być może lepszym sposobem przechowywania danych jest mapa map, gdzie klucz w pierwszej mapie reprezentuje indeks wierszy, a jego wartością jest mapa wierszy, której klucze są indeksem kolumny , z wartością będącą Twoją klasą IntegerNode. A zatem:
Jeśli potrzebujesz mieć możliwość przechodzenia przez macierz wiersz po wierszu, możesz sprawić, że mapa wierszy będzie miała typ a
TreeMap
i to samo dla przechodzenia przez kolumny w kolejności indeksu, ale jeśli nie potrzebujesz tych przypadków,HashMap
jest to szybsze niżTreeMap
. Oczywiście przydatne byłyby metody pomocnicze do pobierania i ustawiania dowolnej komórki, obsługujące nieustawione wartości null.źródło
źródło
przesyłanie w ten sposób działa, ale nadal pozostawia nieprzyjemne ostrzeżenie:
„Bezpieczeństwo typów: wyrażenie typu List [] wymaga niesprawdzonej konwersji.”
to sprytny pomysł, aby uniknąć ostrzeżenia. może trochę przyjemniej jest użyć do tego interfejsu:
następnie
kompiluje się bez ostrzeżeń.
nie wygląda tak źle, prawda?
źródło
List<IntegerNode>[] myMatrix = new IntegerNodeList[numRows];
Jest to subtelny, ale ważny problem. Możesz tylko wstawićIntegerNodeList
tablicę.myMatrix[i] = new ArrayList<IntegerNode>();
rzuciArrayStoreException
.Żadnych ostrzeżeń. NetBeans 6.9.1, jdk1.6.0_24
źródło
Nie ma ogólnego tworzenia tablic w Javie 1.5 (lub 1.6, o ile wiem). Zobacz https://community.oracle.com/message/4829402 .
źródło
Jeśli wykonam następujące czynności, pojawi się odpowiedni komunikat o błędzie
Ale jeśli po prostu usunę typ listy w deklaracji, wydaje się, że ma ona pożądaną funkcjonalność.
Czy te dwie deklaracje różnią się drastycznie w sposób, którego nie jestem świadomy?
EDYTOWAĆ
Ach, myślę, że mam teraz ten problem.
Wydaje się, że Iterowanie po macierzy i inicjowanie list w pętli for działa. Chociaż nie jest tak idealny, jak niektóre inne oferowane rozwiązania.
źródło
Potrzebujesz tablicy List, jedną z alternatyw jest wypróbowanie:
Następnie
node_array[i]
przechowuje węzeł główny (pierwszy)ArrayList<IntegerNode>
lubLinkedList<IntegerNode>
(niezależnie od implementacji listy ulubionych).W tym projekcie tracisz metodę dostępu swobodnego
list.get(index)
, ale nadal możesz przeglądać listę, zaczynając od magazynu węzłów head / fist w tablicy typu safe.Może to być akceptowalny wybór projektu w zależności od przypadku użycia. Na przykład, używam tego projektu do reprezentowania listy sąsiedztwa grafu, w większości przypadków użycia wymaga on i tak przejścia przez listę sąsiedztwa dla danego wierzchołka zamiast swobodnego dostępu do jakiegoś wierzchołka na liście.
źródło