まず、配列がDataType[i][j]
ありj
、7 であることがわかっている場合、使用できる 2 つの最大のインデックスは 6 と 7 ではなく、5 と 6 です。これは、Java 配列インデックスが 0 ベースであるためです。配列を作成するときは、最大インデックス (常に要素数より 1 少ない数) ではなく、要素数を指定します。
第 2に、問題のドメインで既に使用されている多次元配列を使用しても問題はありません。科学的な応用やデータ分析の応用は考えられますが、それ以上のものはありません。反対に、ドメインが多次元配列を使用しないビジネス上の問題をモデル化している場合は、配列が非常に効率的であるように見えるという理由だけで、設計に配列を強制するのではなく、より抽象的なデータ構造を使用する方がおそらく良いでしょう。配列が使用される他の言語での経験より重要な理由、またはその他の理由。
List
多くの情報がなくても、「最初の次元」は型 (たとえば)でより適切に表現できると思いますArrayList
。なんで?そのサイズは実行時に決定されると言うからです(これは、どこかから取得した魔法の数としてではなく、間接的に来ると思います)。 List
s は配列に似ていますが、拡張方法を「知っている」という特殊性があります。プログラムは、ソースから新しい要素を読み取るか、その他の方法でそれらを検出/作成するときに、新しい要素を簡単に追加できます。冒頭や途中でも簡単に挿入できますが、これはまれです。
したがって、最初の次元は次のようになります: ArrayList<
something>
、ここで、somethingは 2 番目の次元の型です。
この 2 番目のディメンションに関して、サイズは 7 ですが、最初の 5 つの項目は単一の値を受け入れ、最後の 2 つの項目は複数の値を受け入れると言っています。これは、7 つの項目が同種ではないことをすでに示しているため、配列は適切に示されていません。この次元は、クラスによってより適切に表現されます。このクラスの構造を理解するために、5 つの単一値要素が同種であるとしましょう (たとえば、型BigDecimal
)。これの最も自然な表現の 1 つは、サイズが既知であるため、配列です。残りの 2 つの多値要素も配列を構成しているようです。ただし、その 2 つの要素のそれぞれに未確認の数のデータ項目が含まれていることを考えると、この配列の要素の型はBigDecimal
前のケースのようにすべきではありませんが、 ArrayList
. これらの要素の型ArrayList
s は、複数の値の型が何であれ (BigDecimal
同様に) です。
最終結果は次のとおりです。
class SecondD {
BigDecimal[] singleValued= new BigDecimal[5] ;
ArrayList<BigDecimal>[] multiValued= new ArrayList<BigDecimal>[2] ;
{
multiValued[0]= new ArrayList<BigDecimal>() ;
multiValued[1]= new ArrayList<BigDecimal>() ;
}
}
ArrayList<SecondD> data= new ArrayList<SecondD>() ;
このコード スニペットでは、構造を宣言するだけでなく、すぐに使用できるように構造を作成しています。純粋な宣言は次のようになります。
class SecondD {
BigDecimal[] singleValued;
ArrayList<BigDecimal>[] multiValued;
}
ArrayList<SecondD> data= new ArrayList<SecondD>() ;
Java では、型 (および構造) の観点から、配列のサイズは重要ではありません。そのため、5 または 2 は表示されません。
データ構造へのアクセスは次のようになります
data.get(130).singleValued[2]
data.get(130).multiValued[1].get(27)
特定のケースでより明確になる可能性のあるバリアントは次のとおりです。
class SecondD {
BigDecimal monday;
BigDecimal tuesday;
BigDecimal wednesday;
BigDecimal thursday;
BigDecimal friday;
ArrayList<BigDecimal> saturday= new ArrayList<BigDecimal>() ;
ArrayList<BigDecimal> sunday= new ArrayList<BigDecimal>() ;
}
ArrayList<SecondD> data= new ArrayList<SecondD>() ;
この場合、各配列を個々の項目に「展開」し、それぞれに名前を付けます。一般的なアクセス操作は次のとおりです。
data.get(130).wednesday
data.get(130).sunday.get(27)
どのバリアントを選択しますか? まあ、それは、さまざまなアイテムでの操作がどの程度類似しているか、または異なるかによって異なります。実行するたびに、、 、、およびを使用して操作するmonday
場合(そうではなく、これらはまったく異なる種類のものであるため、覚えていますか?)、配列の方が優れている可能性があります。たとえば、配列として格納するときにアイテムを合計するには、次のようにするだけです。tuesday
wednesday
thursday
friday
saturday
sunday
element= data.get(130) ;
int sum= 0 ;
for(int e: element.singleValued ) sum+= e ;
展開された場合:
element= data.get(130) ;
int sum= 0 ;
sum+= element.monday ;
sum+= element.tuesday ;
sum+= element.wednesday ;
sum+= element.thursday ;
sum+= element.friday ;
この場合、要素が 5 つしかないため、違いはほとんどありません。最初の方法は物事を少し短くし、2 番目の方法はより明確にします。個人的に、私は明快さのために投票します。ここで、5 項目ではなく 1,000 項目、または 20 項目であった場合、2 番目のケースの繰り返しは多すぎて、最初のケースが優先されます。これについても、別の一般的なルールがあります。すべての要素に個別に名前を付けることができる場合は、正確にそうする方がよいでしょう。要素に名前を付けようとしているときに、数字またはアルファベットの連続した文字を使用していることに気付いた場合 (月の日のように自然に、または物事が異なる名前を持っていないように見えるため)、それは配列です。これら 2 つの基準を適用した後でも、明確でないケースが見つかる可能性があります。この場合、コインを投げて、プログラムの開発を開始し、逆にどうなるか少し考えてみてください。いつでも気が変わることができます。
あなたのアプリケーションが実際に科学的なものである場合、そのような長い (そして役に立たない) 説明を許してください。ただし、私の答えは、似たようなものを探している他の人に役立つ可能性があります。