Utwórz tablicę tablic


175

Chcę utworzyć tablicę arraylist, jak poniżej:

ArrayList<Individual>[] group = new ArrayList<Individual>()[4]

Ale to się nie kompiluje. W jaki sposób mogę to zrobić?


8
Nie mieszaj tablic i kolekcji. W rzeczywistości nie używaj tablic, chyba że masz do czynienia z prymitywami (lub wiesz, co robisz). Tablice są koszmarem użyteczności, sprawiają, że twój kod jest nie do utrzymania.
Sean Patrick Floyd

13
@SeanPatrickFloyd Czy możesz wyjaśnić, dlaczego tablice są koszmarem użyteczności?
użytkownik

3
@crucifiedsoul pewnie. tablica nie może rosnąć, nie można niczego wstawić do tablicy, tablica nie zastępuje standardowych metod, takich jak equals hashcode lub toString itp.
Sean Patrick Floyd

9
@SeanPatrickFloyd okay - cóż, potrzebuję dokładnie czterech arraylists - planuję uzyskać dostęp do każdej z nich według indeksu - nie potrzebuję zewnętrznej tablicy do powiększania lub zmniejszania - nie potrzebuję żadnego toString ani hashcode itp. - - dla mnie tablica jest tutaj oczywistym wyborem - co byś polecił jako alternatywę w tej sytuacji?
BrainSlugs83

4
Okej, to jest stare pytanie, ale mimo to zadam i zobaczę, czy ktoś na nie odpowie. Widzę, jak wszyscy mówią o tym, dlaczego tablica list jest okropnym pomysłem, złą praktyką kodowania itp. Sprawdziłem to, ponieważ uczę się robić łańcuchy mieszające, a definicja łańcucha skrótów to tablica list! Jak więc dokładnie struktura danych centralnego programowania może być okropną praktyką kodowania? Czy to po prostu mieści się w kategorii IYKWYD wspomnianej przez @Sean?
jimboweb

Odpowiedzi:


142

Zgodnie z dokumentacją Oracle :

„Nie można tworzyć tablic typów sparametryzowanych”

Zamiast tego możesz zrobić:

ArrayList<ArrayList<Individual>> group = new ArrayList<ArrayList<Individual>>(4);

Zgodnie z sugestią Toma Hawtinga - tackline jeszcze lepiej:

List<List<Individual>> group = new ArrayList<List<Individual>>(4);

20
List<List<Individual>> group = new ArrayList<List<Individual>>();prawdopodobnie byłoby lepiej.
Tom Hawtin - tackline,

4
Co oznacza „nie można utworzyć tablicy typu ogólnego”? To naprawdę nie ma dla mnie sensu, ponieważ nie jest to rodzaj ogólny, jeśli podasz, co ma mieć, prawda?
Andy

5
Jestem zaskoczony pozytywnymi opiniami, ponieważ nie odpowiada na pytanie (tj. Chcę to zrobić, jak mam to zrobić). Może z wyjątkiem pierwszego zdania.
Florian F

15
dlaczego odniesienie do listy jest lepsze niż ArrayList?
shifu

3
@shifu Odwołanie do listy jest bardziej ogólne niż ArrayList; zadeklarowanie jako List oddziela API ArrayList, które wykracza poza List API. To dobrze, ponieważ upraszcza odniesienie do listy, której API prawdopodobnie zawiera całość tego, do czego List jest potrzebna, bez zaśmiecania API tego odwołania dodatkami, które ma ArrayList. Powinieneś zadeklarować jako ArrayList tylko wtedy, gdy potrzebujesz czegoś konkretnego z jego API, aby było dostępne za pośrednictwem odwołania.
cellepo

98

Jak wspomnieli inni, prawdopodobnie lepiej jest użyć innej listy do przechowywania tablicy ArrayList, ale jeśli musisz użyć tablicy:

ArrayList<Individual>[] group = (ArrayList<Individual>[])new ArrayList[4];

4
Wydaje się, że nikt nie wyjaśnia dobrze, dlaczego i podoba mi się Twój fragment powyżej. dlaczego polecasz używanie listy zamiast tego?
clankill3r

3
Jeśli grupa tablic się nie zmienia, to podejście jest lepsze, ponieważ tablice są szybsze niż klasy List <>.
Borzh

33
Dzięki za odpowiedź na pytanie. Nie ma logicznego powodu, aby automatycznie zakładać, że lista jest lepsza od tablicy bez dalszego kontekstu.
Special Sauce

3
Jest jakiś powód, dla którego byłoby to lepsze od @kelvincer Answer ( ArrayList<String>[] group = new ArrayList[4])? Jakie dodatkowe korzyści daje obsada?
cellepo

2
Powinieneś użyć, new ArrayList<?>[N]aby uniknąć używania surowego typu.
Radiodef

80

To działa:

ArrayList<String>[] group = new ArrayList[4];

1
Ma to satysfakcjonującą korzyść, że dodanie ArrayList dowolnego obiektu poza ArrayList<String>ArrayList<NotString>group
ciągiem

12
To generuje ostrzeżenie:Note: hello.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details.
matematyka

24

Możesz utworzyć klasę rozszerzającą ArrayList

class IndividualList extends ArrayList<Individual> {

}

a następnie utwórz tablicę

IndividualList[] group = new IndividualList[10];

17

Całkowicie tego nie rozumiem, dlaczego wszyscy sugerują typ genetyki w tablicy, szczególnie w tym pytaniu.

A jeśli potrzebuję indeksowania nróżnych arraylistów.

Deklarując List<List<Integer>>, muszę tworzyć n ArrayList<Integer>obiekty ręcznie lub ustawiać pętlę for do tworzenia nlist lub w inny sposób, w jakikolwiek sposób zawsze moim obowiązkiem będzie tworzenie nlist.

Czy to nie wspaniałe, jeśli zadeklarujemy to przez odlewanie jako List<Integer>[] = (List<Integer>[]) new List<?>[somenumber]. Uważam to za dobry projekt, w którym nie trzeba samodzielnie tworzyć wszystkich obiektów indeksujących (arraylistów)

Czy ktoś może mnie oświecić, dlaczego ten (arrayform) będzie złym projektem i jakie są jego wady?


ODPOWIEDŹ, wydaje się, że jest to rodzaj mentalności kultu cargo wywołanego przez okropny system pisania, który wnosi Java do stołu.
BrainSlugs83

@smsIce: To nie jest zły projekt. Problem w tym, że wielu pisarzy nie czyta całego pytania lub nie rozumie go jasno.
testo

16

Możesz utworzyć Array of ArrayList

List<Integer>[] outer = new List[number];
for (int i = 0; i < number; i++) {
    outer[i] = new ArrayList<>();
}

Będzie to pomocne w takich sytuacjach. Znasz rozmiar zewnętrznej. Ale rozmiar wewnętrznych jest różny. Tutaj możesz utworzyć tablicę o stałej długości, która zawiera listy tablic o różnych rozmiarach. Mam nadzieję, że będzie to pomocne.

W Javie 8 i nowszych możesz to zrobić o wiele lepiej.

List<Integer>[] outer = new List[number];
Arrays.setAll(outer, element -> new ArrayList<>());

Jeszcze lepiej przy użyciu odniesienia do metody

List<Integer>[] outer = new List[10];
Arrays.setAll(outer,  ArrayList :: new);

2
Kiedy użyjesz ArrayList::new, wywoła ArrayList(int)contructor z bieżącym indeksem jako argumentem - ArrayList (1), ArrayList (2), ArrayList (3) itd. Tak więc skończysz z tablicami o zbyt małym lub zbyt dużym rozmiarze, w zależności od zastosowania. Chciałbym zniechęcić go używać , a zamiast tego wolą drugie podejście, gdzie wywołanie konstruktora samodzielnie w wyrażeniu lambda.
Genhis

8

To działa, tablica ArrayList. Spróbuj zrozumieć, jak to działa.

import java.util.*;

public class ArrayOfArrayList {
    public static void main(String[] args) {

        // Put the length of the array you need
        ArrayList<String>[] group = new ArrayList[15];
        for (int x = 0; x < group.length; x++) {
            group[x] = new ArrayList<>();
        }

        //Add some thing to first array
        group[0].add("Some");
        group[0].add("Code");

        //Add some thing to Secondarray
        group[1].add("In here");

        //Try to output 'em
        System.out.println(group[0]);
        System.out.println(group[1]);
    }
}

Kredyty dla Kelvincera za niektóre kody.


6

Problem z tą sytuacją polega na tym, że używając tablicy arraylist, uzyskujesz złożoność czasową o (n) dla dodawania w określonej pozycji. Jeśli używasz tablicy, tworzysz lokalizację pamięci, deklarując swoją tablicę, dlatego jest stała


Dodawanie w określonej pozycji to O (n) zarówno dla tablicy, jak i ArrayList. Wypełnienie jest również O (n) dla obu tablic i ArrayList.
Navin

2
Dodawanie w określonej pozycji to O (1) dla tablic. To O (n) dla ArrayList, ale O (1) dla tablic.
aviemet

3

Nie możesz utworzyć tablicy typu ogólnego. Utwórz listę ArrayLists:

 List<ArrayList<Individual>> group = new ArrayList<ArrayList<Individual>>();

lub jeśli NAPRAWDĘ potrzebujesz tablicy (UWAGA: zły projekt!):

 ArrayList[] group = new ArrayList[4];

2
  1. Tworzenie i inicjalizacja

    Object[] yourArray = new Object[ARRAY_LENGTH];
  2. Dostęp do zapisu

    yourArray[i]= someArrayList;

    aby uzyskać dostęp do elementów wewnętrznej ArrayList:

    ((ArrayList<YourType>) yourArray[i]).add(elementOfYourType); //or other method
  3. Dostęp do odczytu

    aby odczytać element tablicy i jako ArrayList użyj rzutowania typu:

    someElement= (ArrayList<YourType>) yourArray[i];

    dla elementu tablicy i: do odczytu elementu ArrayList pod indeksem j

    arrayListElement= ((ArrayList<YourType>) yourArray[i]).get(j);

2

List [] listArr = new ArrayList [4];

Powyższa linia ostrzega, ale działa (tj. Tworzy Array of ArrayList)


1

Aby zadeklarować tablicę ArrayLists statycznie dla, powiedzmy, pozycji duszków jako punktów:

ArrayList<Point>[] positionList = new ArrayList[2];

public Main(---) {
    positionList[0] = new ArrayList<Point>(); // Important, or you will get a NullPointerException at runtime
    positionList[1] = new ArrayList<Point>();
}

dynamicznie:

ArrayList<Point>[] positionList;
int numberOfLists;

public Main(---) {
    numberOfLists = 2;
    positionList = new ArrayList[numberOfLists];
    for(int i = 0; i < numberOfLists; i++) {
        positionList[i] = new ArrayList<Point>();
    }
}

Pomimo ostrzeżeń i pewnych złożonych sugestii, stwierdziłem, że tablica ArrayLists jest eleganckim rozwiązaniem do reprezentowania powiązanych ArrayLists tego samego typu.


1
ArrayList<String>[] lists = (ArrayList<String>[])new ArrayList[10]; 

1

Możesz tworzyć w ten sposób ArrayList<Individual>[] group = (ArrayList<Individual>[])new ArrayList[4];

Musisz utworzyć tablicę typu nieogólnego, a następnie przerzucić ją na typową.



0

Uważam, że jest to łatwiejsze w użyciu ...

static ArrayList<Individual> group[];
......
void initializeGroup(int size)
{
 group=new ArrayList[size];
 for(int i=0;i<size;i++)
 {
  group[i]=new ArrayList<Individual>();
 }

0

Możesz to zrobić :

// Utwórz tablicę typu ArrayList

`ArrayList<Integer>[] a = new ArrayList[n];`

// Dla każdego elementu tablicy stwórz ArrayList

for(int i=0; i<n; i++){ 
    a[i] = new ArrayList<Integer>();
}

0
ArrayList<String> al[] = new ArrayList[n+1];
for(int i = 0;i<n;i++){
   al[i] = new ArrayList<String>();
}

-1

możesz utworzyć List [] i zainicjować je pętlą for. kompiluje się bez błędów:

List<e>[] l;
for(int i = 0; i < l.length; i++){
    l[i] = new ArrayList<e>();
}

działa również z arrayList [] l.


2
l.lengthjest niezdefiniowana w pętli for. Może to być błąd w czasie wykonywania.
bourbaki4481472

l nie jest zainicjowane, aby mieć długość, jest nadal pustym wskaźnikiem, gdy osiągnie pętlę for. tj. Lista <e> [] l = nowa Lista [DŁUGOŚĆ];
Erik,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.