Cara membuat array array di Java

115

Secara hipotetis, saya memiliki 5 objek array string:

String[] array1 = new String[];
String[] array2 = new String[];
String[] array3 = new String[];
String[] array4 = new String[];
String[] array5 = new String[];

dan saya ingin objek array lain berisi 5 objek array string tersebut. Bagaimana saya melakukannya? Bisakah saya meletakkannya di array lain?

Terence Ponce
sumber
43
Pertanyaan noob bisa jadi serius. Nyatanya, sering kali demikian. :-)
TJ Crowder
3
Pertanyaan dan jawaban terkait tidak jelas bagi siapa yang tahu bagaimana penyelarasan memori dilakukan. +1
Benj

Jawaban:

153

Seperti ini:

String[][] arrays = { array1, array2, array3, array4, array5 };

atau

String[][] arrays = new String[][] { array1, array2, array3, array4, array5 };

(Sintaks terakhir dapat digunakan dalam tugas selain pada titik deklarasi variabel, sedangkan sintaks yang lebih pendek hanya berfungsi dengan deklarasi.)

Jon Skeet
sumber
Bisakah Anda menjelaskan lebih lanjut apa yang dilakukan sintaks kedua? Ini agak tidak jelas bagi saya.
Terence Ponce
4
@Terence: Ia melakukan hal yang sama seperti yang pertama: Ini membuat sebuah array referensi array string, diinisialisasi ke nilai array1, array2, array3, array4 dan array5 - yang masing-masing merupakan referensi array string.
Jon Skeet
1
Pertanyaan cepat: Bagaimana saya melakukan ini pada waktu proses jika saya tidak tahu berapa banyak objek array yang akan dibuat?
Terence Ponce
1
@ Terence: Dapatkah Anda memberikan contoh yang lebih spesifik? Ketika Anda menentukan nilai awal pada saat kompilasi, Anda jangan tahu ukuran. Apakah yang Anda maksud seperti itu new String[10][]?
Jon Skeet
Iya. Mirip dengan jawaban Peter.
Terence Ponce
71

mencoba

String[][] arrays = new String[5][];
Peter Lawrey
sumber
1
yang satu ini lebih fleksibel
hetaoblog
Tidakkah seharusnya Anda menentukan ukuran tetap pada array Anda?
Filip
@Filip sudah diperbaiki ke 5. Menyetel level berikutnya akan mengalokasikannya terlebih dahulu, tetapi ini bisa diubah jadi setelan itu mungkin tidak berguna.
Peter Lawrey
8
Bagaimana cara memasukkan data ke dalam array? Jika datanya dinamis?
Prakhar Mohan Srivastava
1
@PrakharMohanSrivastava Anda bisa menyetel elemen satu per satu: arrays[0] = new String[] {"a", "b", "c"}atau gunakan daftar temp: <pre> <code> List <String []> myList = new ArrayList <> (); myList.add (String baru [] {"a", "b", "c"}); myList.add (String baru [] {"d", "e", "f"}); myList.toArray (array); </code> </pre>
kntx
26

Meskipun ada dua jawaban bagus yang memberi tahu Anda bagaimana melakukannya, saya merasa ada jawaban lain yang hilang: Dalam banyak kasus, Anda tidak boleh melakukannya sama sekali.

Array itu rumit, dalam banyak kasus Anda lebih baik menggunakan Collection API .

Dengan Koleksi, Anda dapat menambah dan menghapus elemen dan terdapat Koleksi khusus untuk berbagai fungsi (pencarian berbasis indeks, pengurutan, keunikan, akses FIFO, konkurensi, dll.).

Meskipun tentu saja bagus dan penting untuk mengetahui tentang Array dan penggunaannya, dalam banyak kasus menggunakan Koleksi membuat API jauh lebih mudah dikelola (itulah sebabnya pustaka baru seperti Google Guava hampir tidak menggunakan Array sama sekali).

Jadi, untuk skenario Anda, saya lebih suka Daftar Daftar, dan saya akan membuatnya menggunakan Jambu:

List<List<String>> listOfLists = Lists.newArrayList();
listOfLists.add(Lists.newArrayList("abc","def","ghi"));
listOfLists.add(Lists.newArrayList("jkl","mno","pqr"));
Sean Patrick Floyd
sumber
Sedikit lebih rumit daripada String [] [], tetapi mengizinkan lebih banyak operasi seperti penggabungan data. Namun, solusi Anda tidak memastikan ukuran data, yang bisa menjadi masalah.
Benj
1
@Benj jika perlu, selalu memungkinkan untuk menulis dekorator Daftar yang hanya menerima sejumlah item.
Sean Patrick Floyd
Tepat, dekorator / pembungkus adalah cara yang baik untuk memastikan koherensi. Jadi, cara kita berbicara tentang jauh lebih kompleks daripada array sederhana. Apa yang telah saya lakukan adalah kelas utilitas kecil Array2D <T> yang merangkum beberapa metode dasar seperti exixts (...) dll. Saya memposting ini di bawah.
Benj
6

ada kelas yang saya sebutkan dalam komentar yang kami miliki dengan Sean Patrick Floyd: Saya melakukannya dengan penggunaan khusus yang membutuhkan WeakReference, tetapi Anda dapat mengubahnya dengan objek apa pun dengan mudah.

Berharap ini dapat membantu seseorang suatu hari nanti :)

import java.lang.ref.WeakReference;
import java.util.LinkedList;
import java.util.NoSuchElementException;
import java.util.Queue;


/**
 *
 * @author leBenj
 */
public class Array2DWeakRefsBuffered<T>
{
    private final WeakReference<T>[][] _array;
    private final Queue<T> _buffer;

    private final int _width;

    private final int _height;

    private final int _bufferSize;

    @SuppressWarnings( "unchecked" )
    public Array2DWeakRefsBuffered( int w , int h , int bufferSize )
    {
        _width = w;
        _height = h;
        _bufferSize = bufferSize;
        _array = new WeakReference[_width][_height];
        _buffer = new LinkedList<T>();
    }

    /**
     * Tests the existence of the encapsulated object
     * /!\ This DOES NOT ensure that the object will be available on next call !
     * @param x
     * @param y
     * @return
     * @throws IndexOutOfBoundsException
     */public boolean exists( int x , int y ) throws IndexOutOfBoundsException
    {
        if( x >= _width || x < 0 )
        {
            throw new IndexOutOfBoundsException( "Index out of bounds (get) : [ x = " + x + "]" );
        }
        if( y >= _height || y < 0 )
        {
            throw new IndexOutOfBoundsException( "Index out of bounds (get) : [ y = " + y + "]" );
        }
        if( _array[x][y] != null )
        {
            T elem = _array[x][y].get();
            if( elem != null )
            {
            return true;
            }
        }
        return false;
    }

    /**
     * Gets the encapsulated object
     * @param x
     * @param y
     * @return
     * @throws IndexOutOfBoundsException
     * @throws NoSuchElementException
     */
    public T get( int x , int y ) throws IndexOutOfBoundsException , NoSuchElementException
    {
        T retour = null;
        if( x >= _width || x < 0 )
        {
            throw new IndexOutOfBoundsException( "Index out of bounds (get) : [ x = " + x + "]" );
        }
        if( y >= _height || y < 0 )
        {
            throw new IndexOutOfBoundsException( "Index out of bounds (get) : [ y = " + y + "]" );
        }
        if( _array[x][y] != null )
        {
            retour = _array[x][y].get();
            if( retour == null )
            {
            throw new NoSuchElementException( "Dereferenced WeakReference element at [ " + x + " ; " + y + "]" );
            }
        }
        else
        {
            throw new NoSuchElementException( "No WeakReference element at [ " + x + " ; " + y + "]" );
        }
        return retour;
    }

    /**
     * Add/replace an object
     * @param o
     * @param x
     * @param y
     * @throws IndexOutOfBoundsException
     */
    public void set( T o , int x , int y ) throws IndexOutOfBoundsException
    {
        if( x >= _width || x < 0 )
        {
            throw new IndexOutOfBoundsException( "Index out of bounds (set) : [ x = " + x + "]" );
        }
        if( y >= _height || y < 0 )
        {
            throw new IndexOutOfBoundsException( "Index out of bounds (set) : [ y = " + y + "]" );
        }
        _array[x][y] = new WeakReference<T>( o );

        // store local "visible" references : avoids deletion, works in FIFO mode
        _buffer.add( o );
        if(_buffer.size() > _bufferSize)
        {
            _buffer.poll();
        }
    }

}

Contoh cara menggunakannya:

// a 5x5 array, with at most 10 elements "bufferized" -> the last 10 elements will not be taken by GC process
Array2DWeakRefsBuffered<Image> myArray = new Array2DWeakRefsBuffered<Image>(5,5,10);
Image img = myArray.set(anImage,0,0);
if(myArray.exists(3,3))
{
    System.out.println("Image at 3,3 is still in memory");
}
Benj
sumber
4
+1 untuk usaha Anda, tetapi: alih-alih menginisialisasi bidang int Anda ke -1 dan menetapkannya kembali di Pembuat, Anda harus membuatnya final dan menetapkannya hanya di Pembuat.
Sean Patrick Floyd
1
@Sean: Saya memodifikasi kodenya (memposting yang baru dengan "buffer tanpa GC", termasuk komentar bijak Anda.
Benj