Java:一般的な静的多次元配列

可能であれば、次元ごとに異なるプリミティブデータ型を使用してJavaで静的多次元配列を作成するにはどうすればよいですか?

By static, I mean the primitive array that is not dynamic like an ArrayList would be.

1
@ BheshGurungうん、私はそれを考え出した。むしろ明らかだった。 ;)
追加された 著者 Alerty,
Object [] arr = {new Integer [] {}、新しいString [] {}、新しいDouble [] {}};
追加された 著者 Bhesh Gurung,
はい、私はあまりにも遅く入力していたことがわかりました。
追加された 著者 Bhesh Gurung,

5 答え

You can't.

多次元配列は、定義上、何かの配列の配列の配列です。したがって、最後のものを除くこれらの次元のいずれも配列以外のものになる方法はありません。とにかく、伝統的な定義によって、少なくとも。しかし、あなたが「多次元配列」によって他の何かを意味するならば、それが何であるか教えてください。

「静的」に関しては、それはプログラミングの重い過負荷の言葉であり、私が考えることができるすべての言語は、それを少し違うものを意味するために使用します。 Javaでは、 static は "そのクラスのインスタンスではなくクラスに属しています"を意味します。もう一度、ここで「静的」なものがあれば、そのことを教えてください。

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,
primitive static によって、彼はサイズが変更できません以外は何も意味しません。
追加された 著者 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型です。それについて考える!

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

Foosの多次元配列を持つ場合、最初の次元はFooであり、2番目のFoosの配列、3番目はFooの配列です。変数のタイプは、一番下のものだけです。

質問の更新後に編集:

配列は静的またはプリミティブと呼ばれません。それらのサイズは初期化時に固定されており、プリミティブと共通しているのは、ビルドインであり、場合によっては特殊化されているということです。それらは、プリミティブ型ではないいわゆるプリミティブ型とは対照的に(例えば、演算子は */ - のような独自のものだけを持っていますが)ライブラリでは宣言されていません。

それらをビルドインタイプと呼んでください。

Bhesh Gurungのトリックを使って:

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

ボトムレベルにJPanelがあり、次の次元にJPanelの配列があります。ディメンションを追加して、常に追加の(Array of ...)をラップすることができます。

intやcharやJPanelやJFrameやintやJButtonのような配列には、異なるデータ型を混在させることはできません。差異を抽象化し、JPanelとJFrameに共通の親としてJComponentを使用しますが、オブジェクトではないため、組み込み型int、char、booleanなどでは機能しません。

しかし、autoboxingを使用することはできませんし、intの代わりにIntegerを使用し、charの代わりにCharacterを使用し、Objectを共通の親クラスとして使用しますか?はい、できますが、プリミティブをもう使用していないので、問題を懇願しています。

Danは多次元配列のインデックス作成にdiffernt型を使用して別のことを話しています:

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

バイトまたはショートを使用することに問題はありませんが、配列のサイズをbyteまたはshortとして宣言することによって、そのサイズを制限することはできません。ほとんどの場合、組み込み整数型の境界は、すべての型が負になる可能性があるため、データ型に収まらない(特に365日と考える)ので、境界チェックが必要であり、コンパイルに制限することはできません時間。

しかし、今問題へ:
配列を最初から2次元として宣言することができます:

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

これはうまく動作し、キャストせずにすぐに内部配列にアクセスできます。しかし、コンパイラにとっては、要素がオブジェクト配列であることだけがわかります。基底の型は抽象化されていますので、次のように書くことができます。

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、byte、char、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);
    }
}

「@Test」は JUnit の注釈です。

間違ったデータが配列に入力された場合、このアプローチは実行時にNullPointer例外とClassCast例外の対象となることに注意してください。

0
追加された