Java: Genel Statik Çok Boyutlu Diziler

Mümkünse, boyut başına farklı ilkel veri türleriyle Java'da nasıl statik çok boyutlu bir dizi oluşturabilirim?

Statik olarak, bir ArrayList gibi dinamik olmayan ilkel diziyi kastediyorum.

1
@BheshGurung Yup, anladım. Oldukça açıktı. ;)
katma yazar Alerty, kaynak
Object [] arr = {new Integer [] {}, yeni String [] {}, yeni Double [] {}};
katma yazar Bhesh Gurung, kaynak
Evet, çok yavaş yazdığımı gördüm.
katma yazar Bhesh Gurung, kaynak

5 cevap

Yapamazsın.

Çok boyutlu bir dizi, tanım gereği, bir dizi dizilerin dizisidir .... bir şeydir. Yani, bir diziden başka bir şey olmak dışında, bu boyutların hiçbirinin bir yolu yoktur. En azından, geleneksel tanımla zaten. Ama "çok boyutlu dizi" ile başka bir şey ifade ederseniz, bunun ne olduğunu bize anlatmanız gerekir.

"Statik" için, bu programlamada aşırı yüklü bir sözcük ve düşünebileceğim her dilde biraz farklı bir anlam ifade ediyor. Java'da static , "sınıfın örneklerine değil, bir sınıfa ait" anlamına gelir. Yine, burada "statik" bir şey kastediyorsanız, bunun ne olduğunu bize anlatmanız gerekir.

Edit: As originally posted, the question didn't include the word "primitive". That changes it a bit. Indeed, I agree that it would be nice from a convenience standpoint if Java allowed arrays to be indexed by char or even an enum rather than just int. But it doesn't.

2
katma
Statik olarak, ArrayList gibi dinamik olmayan bir dizi demek istiyorum. Bunu soruma ekleyeceğim.
katma yazar Alerty, kaynak
"İlkel" kelimesini dahil etmediğim için üzgünüm.
katma yazar Alerty, kaynak
İlkel ve statik ile, boyutunda değiştirilemez olmaktan başka bir şey ifade etmiyor, sanırım.
katma yazar user unknown, kaynak

Bazı testlerden sonra basit bir çözümüm var:

Object [][] array = new Object [10][2];
array[0][0] = 2;
array[0][1] = false;
1
katma
Bir dizide farklı türleri birleştirmek kötü bir uygulamadır ve kaçınılmalıdır. Dizideki hangi elemanın, hangi türden bir şey olduğunu, derleyicinin garanti edemeyeceği bir şey olduğunu bilmelisiniz, bu yüzden bu tür bir sorun için dilenen tip sistemini engeller, ve türleri ezberlemek için ek bir teknik kullanmanız gerekir. pozisyonlar. [1] [0] pozisyon dizisinde tekrar bir int ve (1,1) bir boole olacak mı?
katma yazar user unknown, kaynak
Böyle bir diziden değer elde etmenin en iyi yolu ne olurdu? C# Convert.ToInt32 vb içinde java hakkında emin değilim
katma yazar alexey, kaynak

Bir Dizideki Boyutlar her zaman int türünden olur. Bunu düşün!

int a = 4;
int b = 5;

Shoe shoe = new Shoe (Color.RED, 42, "Leather");
Hat hat = new Hat (17, Color.Black);

Foo foo = foos[a][b];
Zilch pop = bars[shoe][hat];//no go

Çok boyutlu bir Foos dizisine sahipseniz, ilk boyut bir Foo'dur, ikincisi bir Foos dizisidir, üçüncüsü ise bir dizi Foo dizisidir. Tek değişken tip altta olan tiptir.

Sorunun güncellenmesinden sonra düzenle:

Diziler statik veya ilkel olarak adlandırılmaz. Büyüklükleri başlangıçta sabittir ve ilkel ile ortak olanları, bazı durumlarda özel olarak tehdit edilen bir yapıdır. Bu ilkel türlerin aksine, bu ilkel olmayanların aksine (örneğin, sadece kendi başlarına, örneğin */- gibi) operatörlerdirler, fakat bu arada onlar da nesnelerdir. ancak kütüphanede bildirilmemiş.

Onlara türlerini oluştur olarak adlandırın.

Bhesh Gurung'un numarasını kullanarak:

Object[] arr = {new Integer[]{}, new String[]{}, new Double[]{}}; 

sorun için yalvarıyor ve boyut başına farklı veri türleri oluşturmuyor. Boyutları ile başlayalım:

// One-dimensional object:
JPanel [] panels = new JPanel [3]; 
// Two-dimensional object:
JPanel [][] panels = new JPanel [3][10]; 

Alt seviyedeki JPanels ve bir sonraki boyutta bir JPanel diziniz var. Daha fazla boyut ekleyebilir ve her zaman eklenmiş (Array of ...) eklenir.

İnt ve char, JPanel ve JFrame veya int ve JButton gibi bir Dizide farklı veri türlerini karıştıramazsınız. Yalnızca farkı belirlediğinizde ve ortak ebeveyn olarak JPanel ve JFrame için bir JComponent kullanırsanız, ancak bunlar int, char, boolean vb. Yapı tipleri için çalışmayacaktır, çünkü bunlar nesne değildir.

Ancak, otomatik kutulamayı kullanamazsınız ve int yerine Integer, char yerine Character karakterini kullanabilir ve sonra da Common parent sınıfını nesne olarak kullanamazsınız? Evet, yapabilirsin, ama sonra artık ilkelleri kullanmıyorsun ve sıkıntı için yalvarıyorsun.

Dan farklı bir şeyden bahsediyor - çok boyutlu dizide indeksleme için farklı türleri kullanarak:

byte  b = 120;
short s = 1000;
String o [][] = new String[b][s];
b = 7;
s = 9;  
o[b][s] = "foobar";
String foo = o[b][s];

Bayt veya kısa mesaj kullanmanın bir sorunu yoktur, ancak bir dizinin boyutunu bayt veya kısa olarak bildirerek kısıtlayamazsınız. Çoğu durumda, bir tamsayı türünün sınırları, özellikle her türün negatif olabileceğinden, bir veri türüne (yılda 365 gün düşünün) uygun olmayacaktır, bu nedenle sınırlama denetimi gereklidir ve bu nedenle derleme ile sınırlandırılamaz. saati.

Ama şimdi belada:
Diziyi baştan iki boyutlu olarak ilan edebiliriz:

Object[][] ar2 = {
    new Integer [] {4, 5, 6}, 
    new String [] {"me", "and", "you"}, 
    new Character [] {'x', 'y', 'z'}};

Bu iyi çalışıyor ve iç dizileri dökmeden hemen erişilebilir hale getiriyor. Ancak, sadece derleyici için, elementlerin Object dizileri olduğu bilinir - temeldeki tip soyutlanır ve böylece şöyle yazabiliriz:

ar2[1][1] = 17;//expected: String
ar2[2][0] = "double you";//expected: Char

Bu kusursuz bir şekilde derlenecek, ancak kendinizi ayağınıza vuruyor ve bir Çalışma Zamanı istisnasını ücretsiz alacaksınız.

İşte bir bütün olarak kaynak:

public class ArrOfMixedArr
{
    public static void main (String args[])
    {
        Object[] arr = {
            new Integer [] {1, 2, 3}, 
            new String [] {"you", "and", "me"}, 
            new Character [] {'a', 'b', 'c'}};
        show (arr);

        byte b = 7;
        short s = 9;
        String o [][] = new String[200][1000];
        o[b][s] = "foobar";
        String foo = o[b][s];

        Object[][] ar2 = {
            new Integer [] {4, 5, 6}, 
            new String [] {"me", "and", "you"}, 
            new Character [] {'x', 'y', 'z'}};
        show (ar2);

       //exeptions:
        ar2[1][1] = 17;//expected: String
        ar2[2][0] = "double you";//expected: Char
    }

    public static void show (Object[] arr)
    {
        for (Object o : arr) 
        {
            if (o instanceof Object[])
                show ((Object[]) o);
            else 
                System.out.print (o.toString() + "\t");
        }
        System.out.println ();
    }
}

Şimdi çözüm nedir? Eğer taban-tür dizileriniz (int, bayt, char, String, JPanel, ...) eşit uzunlukta ise, o zaman gizli bir nesne, bir veritabanı-satırı gibi bir şeyiniz vardır. Bunun yerine bir sınıf kullanın:

class Shoe {
    byte size;
    String manufactor;
    java.math.BigDecimal price;
    java.awt.Color color;
}

Shoe [] shoes = new Shoe [7];

Aynı boyutta farklı türde değilseniz, bunlar ilgisiz olabilir ve ortak bir kapsayıcıya konmamalıdır.

1
katma

Peki, nesnesinin bir dizi dizisini tanımlayabiliyorsunuz ... bir dizi Nesne (boyut olarak çok seviyeli) ve alt seviyedeki her diziyi farklı bir tiple doldurun ... ve Daha sonra, bir değer çıkarmanız gerektiğinde, uygun türe dönüştürün. Gerçekten, ne olduğu için çok fazla iş var. Java, bu tür şeyler için iyi, statik olarak yazılmış bir dildir.

Belki de yeniden düşünmelisin, neden böyle bir veri yapısına ihtiyacın var?

0
katma

Bir nesne dizisi kullanarak efekt alabilirsiniz:

final static Object tryit[][] = {
        {'a',4},
        {'b',7},
        {'c',8},
};
@Test
public void accessArray( ) {
    for (int i = 0; i < tryit.length ; i++) {
        char letter = (Character)tryit[i][0];
        int value = (Integer)tryit[i][1];
        System.out.println(letter + " has value " + value);
    }
}

"@ Test", JUnit ek açıklamasıdır.

Dizide yanlış veri girilirse, bu yaklaşımın çalışma zamanında NullPointer ve ClassCast istisnalarına tabi olacağını unutmayın.

0
katma