Java'da bir dizi nasıl yapılır


115

Varsayımsal olarak, 5 dizgi dizisi nesnem var:

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

ve başka bir dizi nesnesinin bu 5 dizi nesnesini içermesini istiyorum. Nasıl yaparım? Onu başka bir diziye koyabilir miyim?


43
Noob soruları ciddi olabilir. Aslında, sıklıkla öyleler. :-)
TJ Crowder

3
İlgili soru ve cevap, hafıza hizalamasının nasıl yapıldığını kim bilebilirse açık değildir. +1
Benj

Yanıtlar:


153

Bunun gibi:

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

veya

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

(İkinci sözdizimi, değişken bildirim noktası dışındaki atamalarda kullanılabilirken, daha kısa sözdizimi yalnızca bildirimlerle çalışır.)


İkinci sözdiziminin ne yaptığını biraz daha açıklayabilir misiniz? Bu benim için biraz belirsiz.
Terence Ponce

4
@Terence: İlki ile aynı şeyi yapar: Dizi1, dizi2, dizi3, dizi4 ve dizi5 değerleriyle başlatılan bir dizi dizi başvurusu oluşturur - her biri kendi içinde bir dizi dizisi başvurusudur.
Jon Skeet

1
Hızlı soru: Kaç dizi nesnesinin oluşturulacağı hakkında hiçbir fikrim yoksa bunu çalışma zamanında nasıl yapacağım?
Terence Ponce

1
@Terence: Daha spesifik bir örnek verebilir misiniz? Eğer derleme zamanında ilk değerlerini belirterek olduğunuzda, do boyutunu biliyorum. Gibi bir şey mi demek istiyorsun new String[10][]?
Jon Skeet

Evet. Peter'ın cevabına benzer.
Terence Ponce

71

Deneyin

String[][] arrays = new String[5][];

1
bu daha esnek
hetaoblog

Dizinizde sabit bir boyut tanımlamanız gerekmez mi?
Filip 08

@Filip, 5'e sabitlenmiştir. Bir sonraki seviyenin ayarlanması onları önceden tahsis eder, ancak bu değiştirilebilir, bu yüzden ayarlamak yararlı olmayabilir.
Peter Lawrey

8
Diziye nasıl veri eklerim? Dinamik verileri ise?
Prakhar Mohan Srivastava

1
@PrakharMohanSrivastava öğeleri ayrı ayrı ayarlayabilir arrays[0] = new String[] {"a", "b", "c"}veya geçici bir Liste kullanabilirsiniz: <pre> <code> List <String []> myList = new ArrayList <> (); myList.add (yeni Dize [] {"a", "b", "c"}); myList.add (yeni Dize [] {"d", "e", "f"}); myList.toArray (dizileri); </code> </pre>
kntx

26

Size nasıl yapılacağını söyleyen iki mükemmel cevap varken, başka bir cevabın eksik olduğunu hissediyorum: Çoğu durumda bunu hiç yapmamalısınız.

Diziler kullanışsızdır, çoğu durumda Koleksiyon API'sini kullanmanız daha iyidir .

Koleksiyonlar ile öğeleri ekleyip kaldırabilirsiniz ve farklı işlevler için özel Koleksiyonlar vardır (dizin tabanlı arama, sıralama, benzersizlik, FIFO erişimi, eşzamanlılık vb.).

Diziler ve kullanımları hakkında bilgi sahibi olmak elbette iyi ve önemli olsa da, çoğu durumda Koleksiyonların kullanılması API'leri çok daha yönetilebilir hale getirir (bu nedenle Google Guava gibi yeni kitaplıklar Dizileri neredeyse hiç kullanmaz).

Bu yüzden senaryonuz için bir Liste Listesi tercih ederdim ve bunu Guava kullanarak oluştururdum:

List<List<String>> listOfLists = Lists.newArrayList();
listOfLists.add(Lists.newArrayList("abc","def","ghi"));
listOfLists.add(Lists.newArrayList("jkl","mno","pqr"));

String [] [] 'den biraz daha karmaşık, ancak verileri birleştirme gibi daha fazla işleme izin veriyor. Bununla birlikte, çözümünüz veri boyutunu garanti etmez ve bu bir sorun olabilir.
Benj

1
@Benj gerekirse, yalnızca belirli sayıda öğeyi kabul eden bir Liste dekoratörü yazmak her zaman mümkündür.
Sean Patrick Floyd

Kesinlikle, dekoratörler / sarmalayıcılar tutarlılığı sağlamanın iyi bir yoludur. Bu nedenle, konuşma şeklimiz basit dizilerden çok daha karmaşıktır. Yaptığım şey, exixts (...) vb. Gibi bazı temel yöntemleri kapsayan küçük bir yardımcı program sınıfı Array2D <T>. Bunu aşağıda yayınladım.
Benj

6

Sean Patrick Floyd ile yaptığımız yorumda bahsettiğim sınıf var: Bunu WeakReference gerektiren özel bir kullanımla yaptım, ancak herhangi bir nesne ile kolaylıkla değiştirebilirsiniz.

Bunun bir gün birine yardımcı olabileceğini umuyorum :)

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();
        }
    }

}

Nasıl kullanılacağına dair örnek:

// 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");
}

4
Çabanız için +1, ancak: int alanlarınızı -1 olarak başlatmak ve Oluşturucu'da yeniden atamak yerine, onları son hale getirmeli ve yalnızca Oluşturucu'da atamalısınız .
Sean Patrick Floyd

1
@Sean: Kodu değiştirdim (akıllıca yorumunuz dahil olmak üzere "GC arabelleği
içermeyen
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.