Jak mogę dynamicznie dodawać elementy do tablicy Java?

85

W PHP możesz dynamicznie dodawać elementy do tablic, wykonując następujące czynności:

$x = new Array();
$x[] = 1;
$x[] = 2;

Następnie $xbędzie tablica w następujący sposób: {1,2}.

Czy istnieje sposób na zrobienie czegoś podobnego w Javie?

kamikaze_pilot
źródło
4
Dla wszystkich poniższych odpowiedzi używa ArrayList, ale OP specjalnie pyta o Array. też chciałbym wiedzieć.
KJYe.Name 葉家仁
4
odpowiedź brzmi „nie”. Musisz określić rozmiar tablicy (lub wypełnić wszystkie elementy) w momencie deklaracji / tworzenia w Javie. Zobacz java.sun.com/docs/books/jls/second_edition/html/arrays.doc.html
Ritesh,
Zauważyłem, że różne tablice zwrotne funkcji Java, więc przyjrzałem się implementacji listy (filtru) w File.java. Używa listy wewnętrznie, a następnie konwertuje ją na tablicę na końcu. List <String> v = new ArrayList <> (); ... return v.toArray (new String [v.size ()]);
xtempore

Odpowiedzi:

112

Spójrz na java.util.LinkedList lub java.util.ArrayList

List<Integer> x = new ArrayList<Integer>();
x.add(1);
x.add(2);
corsiKa
źródło
21
To doskonała odpowiedź poza jednym kawałkiem. Zwykle w Javie używamy po prostu list zamiast prymitywnych tablic, ale w przypadkach, w których faktycznie potrzebujesz prymitywnej tablicy (np. int[]), Po prostu użyj toArray()metody z listy. Użyj powyższego kodu, ale użyj, x.toArray()aby uzyskać prymitywny Array.
kwartał
1
W 99% przypadków (bardziej jak 99,99999% przypadków), jeśli faktycznie potrzebujesz prymitywnej tablicy, robisz coś źle i powinno być obsługiwane zgodnie z zasadami OO. O ile nie łączysz się z kodem natywnym lub czymś w rodzaju ARRAYobiektów Oracle lub podobnymi głupstwami, znacznie lepiej jest unikać prymitywnych tablic.
corsiKa
11
och, wszystkie te komentarze o tym, jak nie należy używać prymitywnych tablic, gdyby to było takie proste :(
thecoshman
1
@trusktr To jeden z powodów, aby to zrobić. W tym przykładzie jest to bardziej podobne do ... użycie Listodniesienia pozwala nam kopnąć ArrayListdo krawężnika w dowolnym momencie. Jeśli ktoś opublikuje lepszą listę, na przykład SuperDuperAwesomeList, możemy mieć dużo pracy, jeśli użyjemy odniesienia do pliku ArrayList. ArrayList ma rzeczy, których List nie ma. Jeśli polegamy na tych rzeczach w naszym kodzie, zamiana staje się znacznie trudniejsza.
corsiKa
1
@corsiKa, napisz jakieś algorytmy kompresji / kodowania bez prymitywów, a te przypadki są dużo częstsze niż 99. (9). Маtrix zakłada również krzyk prymitywów. Z drugiej strony, jeśli wchodzisz w interakcje z kodem natywnym, używasz DirectBuffers, a nie tablic prymitywnych. W końcu ktoś musi się doczekać, jeśli utkniesz z bazami danych i prezentacją, to ok, ale stwierdzenie 99% jest po prostu głupie.
bestsss
64

Tablice w Javie mają stały rozmiar, więc nie można „dodać czegoś na końcu”, tak jak można by to zrobić w PHP.

Trochę podobne do zachowania PHP jest takie:

int[] addElement(int[] org, int added) {
    int[] result = Arrays.copyOf(org, org.length +1);
    result[org.length] = added;
    return result;
}

Następnie możesz napisać:

x = new int[0];
x = addElement(x, 1);
x = addElement(x, 2);

System.out.println(Arrays.toString(x));

Ale ten schemat jest strasznie nieefektywny dla większych tablic , ponieważ za każdym razem tworzy kopię całej tablicy. (W rzeczywistości nie jest to całkowicie odpowiednik PHP, ponieważ stare tablice pozostają takie same).

Tablice PHP są w rzeczywistości takie same jak Java HashMap z dodanym „kluczem maksymalnym”, więc wiedziałoby, którego klucza użyć w następnej kolejności, oraz dziwną kolejnością iteracji (i dziwną relacją równoważności między kluczami całkowitymi a niektórymi ciągami znaków). Ale w przypadku prostych kolekcji indeksowanych lepiej jest używać listy w Javie, tak jak proponowano inne osoby odpowiadające.

Jeśli chcesz uniknąć używania z Listpowodu narzutu zawijania każdego int w Integer, rozważ użycie reimplementacji kolekcji dla typów pierwotnych, które używają tablic wewnętrznie, ale nie będą kopiować przy każdej zmianie, tylko wtedy, gdy wewnętrzna tablica jest pełna ( podobnie jak ArrayList). (Jednym z szybko przeszukanych przykładów jest ta klasa IntList ).

Guawy zawiera sposoby tworzenia takich opakowań w Ints.asList, Longs.asListitd

Paŭlo Ebermann
źródło
to dużo mądrzejsze niż przyjęte rozwiązanie. żadnych zmarnowanych przedmiotów.
mgła
2
@Mihail: Właściwie normalnie nie polecam tego robić, ponieważ przy każdym dodaniu elementu tworzona jest nowa tablica i kopiowana jest cała zawartość. (Zależy to jednak od twojego przypadku użycia - jeśli rzadko dodajesz / usuwasz cokolwiek, a często iterujesz / wyszukujesz, może to być w porządku.)
Paŭlo Ebermann
ArrayUtils w nowszych wersjach ma metodę, która to robi. Jestem dość leniwy, żeby sprawdzić implementację, ale jestem pewien, że dobrze to napisali.
mgła
1
@MihailStoynov Właściwie to w zasadzie to ArrayListrobi - z tym wyjątkiem, że zamiast zmieniać rozmiar przy każdym dodaniu, gdy zabraknie mu miejsca, podwaja rozmiar, więc nie musi zmieniać rozmiaru tak często.
corsiKa
1
@Mav Nie, ponieważ orgjest o jeden krótszy niż result.
Paŭlo Ebermann
19

Apache Commons ma implementację ArrayUtils, która dodaje element na końcu nowej tablicy:

/** Copies the given array and adds the given element at the end of the new array. */
public static <T> T[] add(T[] array, T element)
zamglenie
źródło
2
W nowszym ArrayUtils jest to: ArrayUtils.appendElement (String.class, origArray, "nowy element")
marmor
12

Widziałem to pytanie bardzo często w sieci i moim zdaniem wiele osób o dobrej reputacji nie udzieliło na nie właściwej odpowiedzi. Dlatego chciałbym tutaj wyrazić swoją własną odpowiedź.

Najpierw należy wziąć pod uwagę, że istnieje różnica między arrayi arraylist.

Pytanie dotyczy dodania elementu do tablicy , a nie ArrayList


Odpowiedź jest dość prosta. Można to zrobić w 3 krokach.

  1. Konwertuj tablicę na arraylistę
  2. Dodaj element do tablicy arrayList
  3. Konwertuj z powrotem nową arrayList na tablicę

Oto prosty obraz tego wprowadź opis obrazu tutaj

I wreszcie kod:

Krok 1:

public List<String> convertArrayToList(String[] array){
        List<String> stringList = new ArrayList<String>(Arrays.asList(array));
        return stringList;
    }

Krok 2:

public  List<String> addToList(String element,List<String> list){

            list.add(element);
            return list;
    }

Krok 3:

public String[] convertListToArray(List<String> list){
           String[] ins = (String[])list.toArray(new String[list.size()]);
           return ins;
    } 

Krok 4

public String[] addNewItemToArray(String element,String [] array){
        List<String> list = convertArrayToList(array);
        list= addToList(element,list);
        return  convertListToArray(list);
}
Jimmy
źródło
1
Głos za mną, ponieważ w końcu ktoś wskazał różnicę między rzeczywistą tablicą a ArrayList ...
JoeG
Najbardziej kompletna i opisowa odpowiedź.
Obaid
11

Możesz użyć, ArrayLista następnie użyć toArray()metody. Ale w zależności od tego, co robisz, możesz w ogóle nie potrzebować tablicy. Sprawdź, czy Listsczegoś więcej chcesz.

Zobacz: Samouczek dotyczący listy Java

Ian Dallas
źródło
5

Prawdopodobnie będziesz chciał użyć do tego ArrayList - dla dynamicznej struktury podobnej do tablicy.

Poduszkowiec pełen węgorzy
źródło
4

Możesz dynamicznie dodawać elementy do tablicy przy użyciu struktur kolekcji w JAVA. Collection Framework nie działa na pierwotnych typach danych.

Ta struktura kolekcji będzie dostępna w pakiecie „java.util. *”

Na przykład, jeśli używasz ArrayList,

Utwórz do niego obiekt, a następnie dodaj liczbę elementów (dowolnego typu, np. String, Integer ... itd.)

ArrayList a = new ArrayList();
a.add("suman");
a.add(new Integer(3));
a.add("gurram");

Teraz dodano 3 elementy do tablicy.

jeśli chcesz usunąć jakiekolwiek dodane elementy

a.remove("suman");

ponownie, jeśli chcesz dodać dowolny element

a.add("Gurram");

Więc rozmiar tablicy dynamicznie rośnie / maleje.

SSSM
źródło
1

Użyj ArrayList lub żongluj tablicami, aby automatycznie zwiększać rozmiar tablicy.

Ibrahim AshShohail
źródło
0

zachowaj liczbę miejsc w tablicy pierwotnej

class recordStuff extends Thread
{
    double[] aListOfDoubles;
    int i = 0;

    void run()
    {
        double newData;
        newData = getNewData(); // gets data from somewhere

        aListofDoubles[i] = newData; // adds it to the primitive array of doubles
        i++ // increments the counter for the next pass

        System.out.println("mode: " + doStuff());
    }

    void doStuff()
    {
        // Calculate the mode of the double[] array

        for (int i = 0; i < aListOfDoubles.length; i++) 
        {
            int count = 0;
            for (int j = 0; j < aListOfDoubles.length; j++)
            {
                if (a[j] == a[i]) count++;
            }
            if (count > maxCount) 
            {
                maxCount = count;
                maxValue = aListOfDoubles[i];
            }
        }
        return maxValue;
    }
}

źródło
Nie ma to nic wspólnego z pierwotnym pytaniem, czy możliwe jest dynamiczne dołączanie nowych elementów do pierwotnej tablicy Java.
Joe Day
0

Jest to prosty sposób dodawania do tablicy w java. Użyłem drugiej tablicy do przechowywania mojej oryginalnej tablicy, a następnie dodałem do niej jeszcze jeden element. Następnie przekazałem tę tablicę z powrotem do oryginalnej.

    int [] test = {12,22,33};
    int [] test2= new int[test.length+1];
    int m=5;int mz=0;
    for ( int test3: test)        
    {          
    test2[mz]=test3; mz++;        
    } 
    test2[mz++]=m;
    test=test2;

    for ( int test3: test)

    {
      System.out.println(test3);
    }
Nenad Bojović
źródło
0

W Javie rozmiar tablicy jest stały, ale można dynamicznie dodawać elementy do tablicy o stałym rozmiarze, używając jej indeksu i pętli for. Poniżej przykład.

package simplejava;

import java.util.Arrays;

/**
 *
 * @author sashant
 */
public class SimpleJava {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here

        try{
            String[] transactions;
            transactions = new String[10];

            for(int i = 0; i < transactions.length; i++){
                transactions[i] = "transaction - "+Integer.toString(i);            
            }

            System.out.println(Arrays.toString(transactions));

        }catch(Exception exc){
            System.out.println(exc.getMessage());
            System.out.println(Arrays.toString(exc.getStackTrace()));
        }
    }

}
Sashant Pardeshi
źródło