web-dev-qa-db-ja.com

Javaでオブジェクトの配列を作成する

私はJavaに不慣れで、しばらくの間Javaでオブジェクトの配列を作成しました。

私は例えばクラスAを持っています -

A[] arr = new A[4];

しかし、これはAへのポインタ(参照)を作成するだけで、4つのオブジェクトを作成することではありません。これは正しいです?作成したオブジェクトの関数や変数にアクセスしようとすると、nullポインタ例外が発生します。私がこれをしなければならなかったオブジェクトを操作する/アクセスすることができるために -

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

これは正しいですか、それとも私は何か悪いことをしていますか?これが正しいならば、それは本当に変です。

編集:私はC + +であなただけの新しいA [4]を言うと、それは4つのオブジェクトを作成するので、私はこの奇妙なことがわかります。

169
user220201

これは正しいです。

A[] a = new A[4];

これを行うのと同様に、4Aの参照を作成します。

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

a1を次のように割り当てずにa1.someMethod()を実行することはできません。

a1 = new A();

同様に、あなたがする必要がある配列で

a[0] = new A();

使用する前に.

235
MeBigFatGuy

これは正しいです。次のこともできます。

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

この構文は、メソッドの引数など、どこにでも配列を作成して初期化するためにも使用できます。

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

はい、それはデフォルト値nullに設定されている参照のみを作成します。 NullPointerExceptionが発生するのはそのためです。オブジェクトを個別に作成して参照を割り当てる必要があります。 Javaで配列を作成する3つのステップがあります -

宣言 - このステップでは、作成する配列のデータ型と次元を指定します。しかし、覚えておいて、我々はまだ寸法の大きさについて言及していない。それらは空のままです。

インスタンス化 - このステップでは、newキーワードを使用して、配列を作成するか、配列にメモリを割り当てます。この段階で、配列の次元のサイズについて説明します。

初期化 - 配列は常にデータ型のデフォルト値に初期化されます。しかし、私たちは自分自身で初期化をすることができます。

Javaで配列を宣言する

これがJavaでの1次元配列の宣言方法です -

int[] array;
int array[];

配列の宣言には前の構文を使用することをお薦めします。これが他の法定宣言の例です -

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

そして、これらは違法な宣言のいくつかの例です -

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

インスタンス化

これが、「インスタンス化」する方法、つまり配列にメモリを割り当てる方法です。

int[] array = new int[5];

JVMがnewキーワードに遭遇すると、JVMは何かのためにメモリを割り当てなければならないことを理解します。 int[5]を指定することで、サイズ5のintsの配列が必要になります。したがって、JVMはメモリを作成し、新しく割り当てられたメモリの参照をint[]型の「参照」に割り当てます。

初期化

ループを使用する - 配列の要素を初期化するためにforループを使用するのが、配列をうまく動かすための最も一般的な方法です。デフォルト値そのものを代入する場合は、forループを実行する必要はありません。JVMがデフォルト値を代入するからです。

オールインワン..! - 一度に宣言、インスタンス化、初期化ができます。これが構文です -

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

ここでは、サイズについては触れません。JVMは5つの値を与えていることがわかるからです。

そのため、参照をインスタンス化するまで、nullのままになります。私の答えがあなたのお役に立てばと思っています。 :)

ソース - Javaの配列

30
Vamsi Sangam

これは、パラメータを取るコンストラクタを使用して、10個の従業員オブジェクトの配列を作成する明確な例です。

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

あなたは正しいです。それとは別に、あるファクトリによって提供される要素で埋められた特定のサイズの配列を作りたいのであれば、Java 8(これは stream API を導入します)から、このワンライナーを使うことができます。

A[] a = Stream.generate(() -> new A()).limit(4).toArray(A[]::new);
  • Stream.generate(() -> new A())はlambda、() -> new A()の実装であるSupplier<A>によって記述された方法で作成された別々のA要素のためのファクトリのようなものです - それはそれぞれの新しいAインスタンスがどのように作成されるべきかを記述します。
  • limit(4)はストリーミングする要素の量を設定します 生成
  • toArray(A[]::new)toArray(size -> new A[size])と書き換えることもできます) - 返されるべき配列のタイプを決定/記述できます。

いくつかのプリミティブ型では、DoubleStreamIntStreamLongStreamを使用できます。これらはさらにrangerangeClosedなどのジェネレータを提供します。

3
Pshemo

はい、それはJavaで正しいですオブジェクトの配列を作るためにいくつかのステップがあります:

  1. 宣言してからインスタンス化する( '4'オブジェクトを格納するためのメモリを作成する):

    A[ ] arr = new A[4];
    
  2. オブジェクトの初期化(この場合、クラスAの4つのオブジェクトを初期化できます)

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

    または

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

今、あなたは今作ったオブジェクトなどから既存のメソッドの呼び出しを始めることができます。

例えば:

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

または

  arr[1].setNumber(x);
0
Jeremy Levett

Javaで新しい配列を宣言する一般的な形式は次のとおりです。

type arrayName[] = new type[numberOfElements];

Typeはプリミティブ型またはObjectです。 numberOfElementsは配列に格納する要素の数です。 この値は変更できません Javaは動的配列をサポートしていないため(オブジェクトを保持するための柔軟で動的な構造が必要な場合Javaコレクションの.

5人の小さな会社にすべての従業員の給与を格納するために配列を初期化しましょう:

int salaries[] = new int[5];

配列の型(この場合はint)は、配列内のすべての値に適用されます。 1つの配列に型を混在させることはできません。

これでsalaries配列が初期化されたので、いくつか値を入れたいと思います。このように初期化中にこれを行うことができます。

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

あるいは、後でこのようにします。

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

アレイ作成のより視覚的な例: enter image description here

配列についてもっと学ぶために、 ガイドをチェックしてください

0
Stas

ジェネリッククラスの場合、ラッパークラスを作成する必要があります。例えば:

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

"総称配列を作成できません"

代わりに使ってください。

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