Java: Generic Статычныя Шматмерныя масівы

Калі гэта магчыма, то як я магу стварыць <моцнага> статычнага мнагамерны масіў у Java з рознымі прымітыўнымі тыпамі дадзеных у вымярэнне?

Да статычным, я маю на ўвазе прымітыўны масіў, які не з'яўляецца дынамічным, як ArrayList будзе.

1
@BheshGurung Так, я зразумеў. Гэта было даволі відавочна. ;)
дададзена аўтар Alerty, крыніца
<Код> Object [] обр = {новае Цэлае [] {}, новы радок [] {}, новы двайны [] {}};
дададзена аўтар Bhesh Gurung, крыніца
Так, я бачыў, што я друкаваў занадта павольна.
дададзена аўтар Bhesh Gurung, крыніца

5 адказы

Вы не можаце.

Мнагамерны масіў, па вызначэнні, масіў масіваў масіваў .... что-то. Такім чынам, няма ніякага спосабу для любога з гэтых памераў, за выключэннем апошняга, каб быць нічым іншым, чым масіў. Прынамсі, у традыцыйным разуменні ў любым выпадку. Але калі вы маеце на ўвазе нешта іншае з дапамогай «шматмернага масіва», вы павінны сказаць нам, што гэта такое.

Што ж тычыцца «статыка», гэта значыць моцна перагружаны слова ў праграмаванні, і кожны мова, які я магу думаць выкарыстоўвае гэта, каб азначаць нешта крыху іншае. У Java, статычны азначае, што «належыць да класа, а не да асобнікам гэтага класа.» Зноў жа, калі вы маеце на ўвазе нешта іншае ад «статыкі», вы павінны сказаць нам, што гэта такое.

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
дададзена
Да статычным, я маю на ўвазе масіў, які не з'яўляецца дынамічным, як ArrayList. Я дадам, што ў маім пытанні.
дададзена аўтар Alerty, крыніца
На жаль пра не уключаючы слова «прымітыўны».
дададзена аўтар Alerty, крыніца
Па прымітыўнага і статычнаму ён не азначае нічога, акрамя нязменнага памеру , я думаю.
дададзена аўтар user unknown, крыніца

Пасля некаторага тэставання, у мяне ёсць простае рашэнне:

Object [][] array = new Object [10][2];
array[0][0] = 2;
array[0][1] = false;
1
дададзена
Спалучэнне розных тыпаў у масіве з'яўляецца дрэннай практыкай і варта пазбягаць. Вы павінны ведаць, што элемент масіва мае які тып, тое, што кампілятар не можа гарантаваць, дык гэта абыйсці тып-сістэма ака кленчанне на непрыемнасць, і вы павінны выкарыстоўваць дадатковы метад для запамінання тыпаў/пазіцыі. У масіве пазіцыі [1] [0], вы зноў мець Int, і ў (1,1) булева?
дададзена аўтар user unknown, крыніца
што было б лепшым спосабам для здабывання значэнняў з такога масіва? У C# яго Convert.ToInt32 і г.д., не ўпэўнены, што Java
дададзена аўтар alexey, крыніца

Памеры ў масіве заўсёды ад тыпу міжнар. Падумайце пра гэта!

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

Калі ў вас ёсць мнагамерны масіў Фооса, першае вымярэнне з'яўляецца Foo, то другім масіў Фооса, трэці масіў масіва Foo. Толькі тып зменнай з'яўляецца адзін у ніжняй часткі.

Рэдагаванне пасля абнаўлення пытання:

Масівы не называюцца статычнымі або прымітыўным. Іх памер фіксуецца пры ініцыялізацыі, і што яны маюць агульны з прымітываў, што яны з'яўляюцца Buildin, які threated асаблівым у некаторых выпадках. Яны - у адрозненне ад так званых прымітыўных тыпаў, якія не з'яўляюцца, што прымітыў (у іх ёсць, напрыклад, аператары, выключна для сваіх, як */- ), але пакуль што яны з'яўляюцца аб'ектамі, але не абвешчаная ў бібліятэцы.

Назавіце іх пабудаваць у-тыпаў .

Выкарыстоўваючы трук Bhesh Гурунг у:

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

з'яўляецца кленчанне на непрыемнасць, і ён не зроблены з розных тыпаў дадзеных на вымярэнне. Давайце пачнем з памерамі:

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

Вы JPanels на ніжнім узроўні, а таксама масіў JPanel на наступным вымярэнні. Вы можаце дадаць больш памеру, і заўсёды атрымаеце дадатковы (масіў ...), абгорнуты вакол.

Вы не можаце змешваць розныя тыпы дадзеных у масіве, як міжнар і голец або JPanel і JFrame або міжнар і JButton. Толькі калі абстрагавацца за розніцы і выкарыстоўваць JComponent для JPanel і JFrame як агульны продак, але гэта не будзе працаваць для разварушвання ў тыпы INT, паўкокс, лагічнае значэнне і гэтак далей, таму што яны не з'яўляюцца аб'ектамі.

Але вы не можаце выкарыстоўваць Autoboxing і выкарыстоўваць Integer замест міжнар, Character замест паўкокс, а затым выкарыстоўваць аб'ект у якасці агульнага бацькоўскага класа? Так, вы маглі б, але тады вы не выкарыстоўваеце прымітывы больш, і вы выпрошваючы непрыемнасці.

Дэн кажа пра іншыя рэчы - выкарыстоўваючы розныя тыпы для індэксацыі ў шматмерных масіве:

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];

Там няма ніякіх праблем з выкарыстаннем байтаў ці шорты, але вы не можаце абмежаваць памер масіва, абвясціўшы яго ў якасці байта або кароткага замыкання. У большасці выпадкаў мяжа ўбудаванай цэлага тыпу не змяшчаецца на тып дадзеныя (думаюць, 365 дзён у год), тым больш, што ўсе тыпы могуць атрымаць адмоўныя, таму межы праверка неабходная хоць і не можа быць абмежаваная для кампіляцыі час.

Але цяпер бяда:
Мы маглі б аб'явіць масіў як двухмерных з самага пачатку:

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

Гэта выдатна працуе, і робіць ўнутраныя масівы даступныя адразу без ліцця. Але вядома, толькі для кампілятара, што элементы масіваў Object - асноўны тып абстрагуюцца, і таму мы можам напісаць:

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

Гэта будзе кампіляваць бездакорна, але вы здымаеце сабе ў нагу і атрымаць выканаўчую выключэнне бясплатна.

Вось крыніца ў цэлым:

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

Цяпер, што такое рашэнне? Калі вашы базавыя тыпы-масівы (INT, байты, паўкокс, String, JPanel, ...) маюць аднолькавую даўжыню, то ў вас ёсць нешта накшталт схаванага аб'екта, базы дадзеных-радка. Выкарыстоўвайце клас замест гэтага:

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

Shoe [] shoes = new Shoe [7];

Калі вы не маеце розныя тыпы аднаго і таго ж памеру, што яны могуць быць звязаныя паміж сабой, і не павінны быць змешчаны ў агульны кантэйнер.

1
дададзена

Ну, вы можа вызначыць масіў масіў ... масіў аб'ектаў (укладзены з такой колькасцю узроўняў, як памеры) і на ніжнім узроўні запаўнення кожнага масіва з розным тыпам ... і тады, калі вам трэба атрымаць значэнне, прыводзьце яго да адпаведнага тыпу. Занадта шмат працы для таго, што варта, на самай справе. Java не добра для такога роду рэчаў, будучы статычна тыпізаваных мову.

Можа быць, вам варта перагледзець, чаму б вам патрэбна такая структура дадзеных.

0
дададзена

Вы можаце атрымаць эфект, выкарыстоўваючы масіў аб'ектаў:

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

<ЕМ> The "@Test" з'яўляецца JUnit annnotation.

Звярніце ўвагу, гэты падыход будзе падлягаць NullPointer і ClassCast выключэнне падчас выканання, калі няправільна дадзеныя ўводзяцца ў масіве.

0
дададзена