In first place, if you have an array DataType[i][j]
and j
is known to be 7, the 2 greatest indexes you can use are 5 and 6, not 6 and 7. This is because Java array indexes are 0-based. When creating the array you indicate the number of elements, not the maximum index (which always is one less than number of elements).
In second place, there is nothing wrong with using multidimensional arrays when the problem domain already uses them. I can think of scientific applications, data analysis applications, but not many more. If, on the contrary, you are modelling a business problem whose domain does not use multidimensional arrays, you are probably better off using more abstract data structures instead of forcing arrays into the design just because they seem very efficient, experience in other languages where arrays are more important, or other reasons.
Without having much information, I'd say your "first dimension" could be better represented by a List
type (say ArrayList
). Why? Because you say its size is determined at runtime (and I assume this comes indirectly, not as a magic number that you obtain from somewhere). List
s are similar to arrays but have the particularity that they "know" how to grow. Your program can easily append new elements as it reads them from a source or otherwise discovers/creates them. It can also easily insert them at the beginning or in the middle, but this is rare.
So, your first dimension would be: ArrayList<
something>
, where something is the type of your second dimension.
Regarding this second dimension, you say that it has a size of 7, but that the first 5 items accept single values while the last 2 multiple ones. This is already telling me that the 7 items are not homogeneous, and thus an array is ill-indicated. This dimension would be much better represented by a class. To understand this class's structure, let's say that the 5 single-valued elements are homogenous (of type, say, BigDecimal
). One of the most natural representations for this is array, as the size is known. The 2 remaining, multi-valued elements also seem to constitute an array. However, given that each of its 2 elements contains an unidentified number of data items, the element type of this array should not be BigDecimal
as in the previous case, but ArrayList
. The type of the elements of these ArrayList
s is whatever the type of the multiple values is (say BigDecimal
too).
The final result is:
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>() ;
In this code snippet I'm not only declaring the structures, but also creating them so they are ready to use. Pure declaration would be:
class SecondD {
BigDecimal[] singleValued;
ArrayList<BigDecimal>[] multiValued;
}
ArrayList<SecondD> data= new ArrayList<SecondD>() ;
Array size is not important in Java from a type (and thus structural) point of view. That's why you don't see any 5 or 2.
Access to the data structure would be like
data.get(130).singleValued[2]
data.get(130).multiValued[1].get(27)
A possible variant that could be much clearer in certain cases is
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>() ;
In this case we are "expanding" each array into individual items, each with a name. Typical access operations would be:
data.get(130).wednesday
data.get(130).sunday.get(27)
Which variant to choose? Well, that depends on how similar or different the operations with the different itemes are. If every time you will perform and operation with monday
you will also perform it with tuesday
, wednesday
, thursday
, and friday
(not saturday
and sunday
because these are a completely different kind of thing, remember?), then an array could be better. For example, to sum the items when stores as an array it's only necessary:
element= data.get(130) ;
int sum= 0 ;
for(int e: element.singleValued ) sum+= e ;
While if expanded:
element= data.get(130) ;
int sum= 0 ;
sum+= element.monday ;
sum+= element.tuesday ;
sum+= element.wednesday ;
sum+= element.thursday ;
sum+= element.friday ;
In this case, with only 5 elements, the difference is not much. The first way makes things slightly shorter, while the second makes them clearer. Personally, I vote for clarity. Now, if instead of 5 items they would have been 1,000 or even as few as 20, the repetition in the second case would have too much and the first case preferred. I have another general rule for this too: if I can name every element separately, then it's probably better to do exactly so. If while trying to name the elements I find myself using numbers or sequential letters of the alphabet (either naturally, as in the days of the month, or because things just don't seem to have different names), then it's arrays. You could still find cases that are not clear even after applying these two criteria. In this case toss a coin, start developing the program, and think a bit how things would be the other way. You can change your mind any time.
If your application is indeed a scientific one, please forgive me for such a long (and useless) explanation. My answer could help others looking for something similar, though.