49

In Java, is a multidimensional array stored in column-major or row-major order?

Community
  • 1
  • 1
Zouzias
  • 2,330
  • 1
  • 22
  • 32
  • 1
    Java doesn't really have 2d arrays, though its 1d arrays can hold references to other arrays for the 2d effect. So this question just doesn't really make sense for Java. – Don Roby Jul 08 '11 at 22:12
  • I removed the reference about C, Matlab, etc. and repeated the question in the main body. I hope now my question is clear. – Zouzias Jul 10 '11 at 17:55
  • 5
    Voting to reopen. *"It's difficult to tell what is being asked here"* - really? It is extremely clear to me. We even got three good answers. – Saturn Mar 10 '15 at 21:27
  • 3
    Why is this question closed? It baffles me to come across such perfectly valid, meaningful questions which are closed. – ajay Aug 03 '16 at 17:49

3 Answers3

95

Java doesn't have multi-dimensional arrays. It has arrays of arrays. So for instance,

int[][]

...is an array of int[] (and of course int[] is an array of int).

Consequently, Java is neither column-major nor row-major order (but see note below about how to read a[2][3]), because while a given array's entries are stored in a contiguous block of memory, the subordinate arrays those entries point to are object references to completely separate, unrelated blocks of memory. This also means that Java's arrays of arrays are inherently jagged: The entry at [0] might refer to a 3-slot array, the one at [1] might refer to a 4-slot array, [2] might not refer to an array at all (it could have null), and perhaps [3] refers to a 6-slot array.

A picture is worth 1k-24 words and all that:

                         +−−−−−−−−+
                   +−−−−>| int[]  |
+−−−−−−−−−−−+      |     +−−−−−−−−+
|  int[][]  |      |     | 0: int |
+−−−−−−−−−−−+      |     | 1: int |
| 0: int[]  |−−−−−−+     | 2: int |
| 1: int[]  |−−−−−−+     +−−−−−−−−+
| 2: null   |      |
| 3: int[]  |−−+   |     +−−−−−−−−+
+−−−−−−−−−−−+  |   +−−−−>| int[]  |
               |         +−−−−−−−−+
               |         | 0: int |
               |         | 1: int |
               |         | 2: int |
               |         | 3: int |
               |         +−−−−−−−−+
               |
               |         +−−−−−−−−+
               +−−−−−−−−−| int[]  |
                         +−−−−−−−−+
                         | 0: int |
                         | 1: int |
                         | 2: int |
                         | 3: int |
                         | 4: int |
                         | 5: int |
                         +−−−−−−−−+

Once you know that, you know that (say) a[2][3] means "Get the array referenced by the entry at index 2 of a, then get the entry referenced by index 3 of that subordinate array." I think of it as fairly similar to row-major order, but it's not quite the same thing.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 4
    More complete answer than mine. +1. Java has no multi-dimensional arrays in terms of memory storage -- but the JLS itself refers to Java's arrays of arrays loosely as "multi-dimensional arrays." – Andy Thomas Jul 08 '11 at 22:33
  • 2
    Thanks for the answer, T.J. Crowder. So, I guess it is more efficient to scan your array of 1D arrays in row-major ordering. – Zouzias Jul 10 '11 at 17:59
  • 1
    @Zouzias: *Probably*. And cache the reference to the row, since it is an object reference. E.g., in Java, `a = x[3][2];` means `y = x[3]; a = y[2];` whereas in (say) C, `a = x[3][2];` would mean `a = *(x + (3 * 2));` So you want to do that `y = x[3]` once and keep a reference to it (though some JVMs -- Sun/Oracle's HotSpot, for instance -- are very good at doing that for you). – T.J. Crowder Jul 10 '11 at 18:24
  • Really nice explanation of Jagged arrays in Java, yeah I agree that Java arrays unlike C arrays don't require any order when they are being allocated. Its simply thought in a recursive way as array of array of array and so on. – AnkitSablok Aug 31 '15 at 00:46
  • So, it doesn't matter in java you iterate row wise or column wise? (Performance perspective) – Vivek Aug 19 '23 at 17:57
  • @Vivek - I haven't done any Java performance optimisation (or Java work at all) in ages, but both in general and *particularly* with the Java VM, the best way to handle performance aspects is to write the code that's clear to you and others, and then **If** there's a performance issue, try it another way and use [proper benchmarks](https://stackoverflow.com/questions/504103/) to see whether it's better or worse. Have fun! – T.J. Crowder Aug 20 '23 at 10:41
6

In Java, you only have one dimensional arrays.

2D arrays are basically just one dimensional arrays of one dimensional arrays.

int[ ][ ] table;

table = new int[3][ ];

table[0] = new int[5];

table[1] = new int[5];

table[2] = new int[5];
ʇolɐǝz ǝɥʇ qoq
  • 717
  • 1
  • 15
  • 30
Kal
  • 24,724
  • 7
  • 65
  • 65
5

Neither. What we may sometimes think of as two-dimensional array in Java is actually an array of references to arrays. It's not stored linearly in memory.

The Java Language specification notes this in the introduction:

The language supports arrays of arrays, rather than multidimensional arrays.

This has several implications.

  • Arrays of arrays can be jagged -- member arrays can have different lengths.
  • The members of an outer array are references, and can be null.
  • Cloning an outer array is shallow -- the member arrays are shared between the original and the clone.

From the JLS, section 10.2, "Array Variables":

A single variable of array type may contain references to arrays of different lengths, because an array's length is not part of its type.

From the JLS, section 10.7, "Array Members":

A clone of a multidimensional array is shallow, which is to say that it creates only a single new array. Subarrays are shared.

Andy Thomas
  • 84,978
  • 11
  • 107
  • 151
  • Are you sure? I thought it's Row-Major order – Eng.Fouad Jul 08 '11 at 22:04
  • 4
    It's similar, because the columns in a particular row are stored contiguously. However, the rows themselves are not stored contiguously. A 2D array in C is one block of memory. It can be important to know whether the data is laid in that block in row-major order or column-major. But in one-dimension arrays, there's only one layout. – Andy Thomas Jul 08 '11 at 22:12