Java'da bir nesne dizisi oluşturma


197

Java için yeniyim ve şimdilik Java'da bir dizi nesne oluşturdum.

Örneğin A sınıfım var -

A[] arr = new A[4];

Ancak bu sadece A4 nesneye değil , yalnızca işaretçiler (referanslar) oluşturur . Bu doğru mu? Oluşturulan nesnelerdeki işlevlere / değişkenlere erişmeye çalıştığımda boş bir işaretçi istisnası aldığımı görüyorum. Nesneleri manipüle edebilmek / erişebilmek için bunu yapmam gerekiyordu:

A[] arr = new A[4];
for (int i = 0; i < 4; i++) {
    arr[i] = new A();
}

Bu doğru mu yoksa yanlış bir şey mi yapıyorum? Bu doğruysa gerçekten tuhaf.

EDIT: Bu garip buluyorum çünkü C ++ 'da sadece yeni söyleyin A[4]ve dört nesne oluşturur.


17
Ben sadece bu son derece yararlı bir soru olduğunu söylemek istedim; sorduğun için teşekkürler.
pandorym

Yanıtlar:


262

Doğru.

A[] a = new A[4];

... Abunu yapmaya benzer 4 referans oluşturur :

A a1;
A a2;
A a3;
A a4;

Şimdi böyle a1.someMethod()ayırmadan yapamazsınız a1:

a1 = new A();

Benzer şekilde, dizi ile bunu yapmanız gerekir:

a[0] = new A();

... kullanmadan önce.


10
Bu cevap bana bir sürü karışıklık kazandırdı, varlığınız için teşekkür ederim.
pandorym

1
Ben de bu karışıklık vardı, çünkü ben C ++ arka plan her zaman C ++ Java'nın newanahtar kelime gibi de yapıcı çağırır ve I bellek tahsis varsayılır . Java newsadece referansları C ++ ile karşılaştırıldığında gerçek nesne değil oluşturur sanırım . Cevap için teşekkürler.
Krishna Oza

1
@Krishna_Oza, burada C ++ 'dan fark yok. İlki newbir dizi nesnesi oluşturur. Bunlar dinamik olarak atanan nesnelerdir ("yığın"). Yani benzer C ++ kodu olurdu A **a = new A*[4]; for (int i = 0; i < 4; ++i) { a[i] = new A(); }.
Vsevolod Golovanov

1
Ben yeni referanslar oluşturur olsun, ama neden de yapıcı C ++ 'da olduğu gibi dizinin her öğe için başlatmak değil. Bu aptalca olabilir, ama sormak istiyorum, eğer yaparsak, herhangi bir sorun olurdu ?? @MeBigFatGuy
Jasser

2
@Jasser - elementler için hangi yapıcı çağırırdınız? Tek eleman oluşturucu bir grup argüman alırsa ne olur? Bu nesneleri nasıl yaratırsınız?
MeBigFatGuy

78

Doğru. Ayrıca şunları da yapabilirsiniz:

A[] a = new A[] { new A("args"), new A("other args"), .. };

Bu sözdizimi, bir yöntem bağımsız değişkeninde olduğu gibi herhangi bir yerde bir dizi oluşturmak ve başlatmak için de kullanılabilir:

someMethod( new A[] { new A("args"), new A("other args"), . . } )

35

Evet, yalnızca varsayılan değer null olarak ayarlanmış başvurular oluşturur. Bu nedenle bir NullPointerException alıyorsunuz Nesneleri ayrı ayrı oluşturmanız ve başvuruyu atamanız gerekir. Java'da diziler oluşturmak için 3 adım vardır -

Beyan - Bu adımda, oluşturacağımız dizinin veri türünü ve boyutlarını belirtiyoruz. Ancak unutmayın, henüz boyutların boyutlarından bahsetmiyoruz. Boş bırakılırlar.

Örnekleme - Bu adımda, yeni anahtar kelimeyi kullanarak diziyi oluşturur veya dizi için bellek ayırırız. Bu adımda dizi boyutlarının boyutlarından bahsediyoruz.

Başlatma - Dizi her zaman veri türünün varsayılan değerine sıfırlanır. Ancak kendi başlangıçlarımızı yapabiliriz.

Java'da Dizileri Bildirme

Java'da tek boyutlu bir diziyi bu şekilde ilan ediyoruz -

int[] array;
int array[];

Oracle, dizileri bildirmek için eski sözdizimini kullanmanızı önerir. İşte yasal beyannamelere başka örnekler -

// One Dimensional Arrays
int[] intArray;             // Good
double[] doubleArray;

// One Dimensional Arrays
byte byteArray[];           // Ugly!
long longArray[];

// Two Dimensional Arrays
int[][] int2DArray;         // Good
double[][] double2DArray;

// Two Dimensional Arrays
byte[] byte2DArray[];       // Ugly
long[] long2DArray[];

Bunlar yasadışı beyanlara bazı örnekler.

int[5] intArray;       // Don't mention size!
double{} doubleArray;  // Square Brackets please!

Destekleme

Bir dizi için bu şekilde “örnek oluştururuz” veya bellek ayırırız -

int[] array = new int[5];

JVM newanahtar kelimeyle karşılaştığında, bir şey için bellek ayırması gerektiğini anlar. Ve belirterek int[5], int5 büyüklüğünde bir s dizisi istediğimizi kastediyoruz, bu nedenle JVM hafızayı oluşturur ve yeni tahsis edilen belleğin referansını bir "referans" türüne diziye atarint[]

Başlatma

Döngü Kullanma - Bir dizinin öğelerini başlatmak için bir for döngüsü kullanmak, diziyi çalıştırmanın en yaygın yoludur. Varsayılan değeri kendisi atayacaksanız bir for döngüsü çalıştırmanıza gerek yoktur, çünkü JVM bunu sizin için yapar.

Hepsi bir arada..! - Dizimizi tek seferde ilan edebilir, örnekleyebilir ve başlatabiliriz. İşte sözdizimi -

int[] arr = {1, 2, 3, 4, 5};

Burada, boyuttan bahsetmiyoruz, çünkü JVM 5 değer verdiğimizi görebiliyor.

Yani, somutlaştırılana kadar referanslar boş kalır. Umarım cevabım sana yardımcı olmuştur ..! :)

Kaynak - Java'daki Diziler


5

Parametre alan bir kurucu ile 10 çalışan nesnesi dizisi oluşturmanın açık örneği:

public class MainClass
{  
    public static void main(String args[])
    {
        System.out.println("Hello, World!");
        //step1 : first create array of 10 elements that holds object addresses.
        Emp[] employees = new Emp[10];
        //step2 : now create objects in a loop.
        for(int i=0; i<employees.length; i++){
            employees[i] = new Emp(i+1);//this will call constructor.
        }
    }
}

class Emp{
    int eno;
    public Emp(int no){
        eno = no;
        System.out.println("emp constructor called..eno is.."+eno);
    }
}

3

Haklısın. Bunun yanı sıra, bazı "fabrika" tarafından sağlanan öğelerle dolu belirli boyutta bir dizi oluşturmak istiyorsak, Java 8'den beri ( akış API'sini tanıtan ) bu tek astarı kullanabiliriz:

A[] a = Stream.generate(() -> new A()).limit(4).toArray(A[]::new);
  • Stream.generate(() -> new A())lambda tarafından tanımlanan şekilde oluşturulan ayrı A öğeleri için fabrika gibidir, () -> new A()bu da Supplier<A>her yeni A örneğinin nasıl oluşturulması gerektiğini tanımlar.
  • limit(4)akışın üreteceği öğe miktarını ayarlar
  • toArray(A[]::new)(ayrıca yeniden yazılabilir toArray(size -> new A[size])) - döndürülecek dizi türüne karar vermemizi / tanımlamamızı sağlar.

Kullanabileceğiniz bazı ilkel türleri için DoubleStream, IntStream, LongStreamayrıca gibi oluşturma araçları içeren range rangeClosedve birkaç başka.


0

Evet, Java'da bir nesne dizisi yapmak için birkaç adım vardır:

  1. Bildirme ve ardından Örnekleme ('4' nesnesini saklamak için bellek oluşturun):

    A[ ] arr = new A[4];
  2. Nesneleri Başlatma (Bu durumda A sınıfı 4 nesneyi Başlatabilirsiniz)

    arr[0] = new A();
    arr[1] = new A();
    arr[2] = new A();
    arr[3] = new A();

    veya

    for( int i=0; i<4; i++ )
      arr[i] = new A();

Artık az önce yaptığınız nesnelerden mevcut yöntemleri çağırmaya başlayabilirsiniz.

Örneğin:

  int x = arr[1].getNumber();

veya

  arr[1].setNumber(x);

0

Genel sınıf için bir sarıcı sınıf oluşturmak gerekir. Örneğin:

Set<String>[] sets = new HashSet<>[10]

sonuçları: "Genel dizi oluşturulamıyor"

Bunun yerine kullanın:

        class SetOfS{public Set<String> set = new HashSet<>();}
        SetOfS[] sets = new SetOfS[10];  

Bu satır, Set türünün Dize olduğu Kümeler dizisi oluşturmaya çalıştığınız anlamına mı geliyor?
sofs1

0

Java'da yeni bir dizi bildirmek için genel form aşağıdaki gibidir:

type arrayName[] = new type[numberOfElements];

Burada tür, ilkel tür veya Nesne'dir. numberOfElementsdiziye depolayacağınız öğelerin sayısıdır ve Java dinamik dizileri desteklemediği için bu değer değişemez (nesneleri tutmak için esnek ve dinamik bir yapıya ihtiyacınız varsa bazı Java koleksiyonlarını kullanmak isteyebilirsiniz).

Tüm çalışanların maaşlarını 5 kişilik küçük bir şirkette saklamak için bir dizi başlatalım:

int salaries[] = new int[5];

Dizinin türü (bu durumda int) dizideki tüm değerlere uygulanır. Bir dizideki türleri karıştıramazsınız.

Artık maaş dizimizi başlattığımıza, içine bazı değerler koymak istiyoruz. Bunu başlatma sırasında şu şekilde yapabiliriz:

int salaries[] = {50000, 75340, 110500, 98270, 39400};

Veya bunu daha sonraki bir noktada yapmak için:

salaries[0] = 50000;
salaries[1] = 75340;
salaries[2] = 110500;
salaries[3] = 98270;
salaries[4] = 39400;

Dizi oluşturmaya daha görsel bir örnek: resim açıklamasını buraya girin

Diziler hakkında daha fazla bilgi edinmek için kılavuza göz atın .

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.