red symbol man
red symbol man

Reputation: 78

How to initialize a large constant array in Java elegantly?

My question is related to the error message discussed e.g. here: The code for the static initializer is exceeding the 65535 bytes limit error in java?

In a class I need a 2-dimensional array with about 4000 short constants which were expensively pre-estimated in a different software. I decided to initialize it like this:

private static final short[][] DataTable = {
    {32767,32767,32537,32260,31957},
    {14485,14441,14393,14338,14277,14210,14135,14052,13960},
    // Many more lines here ...
    {   60,   67,   75,   84,   95,  106,  119,  133}
}

But due to the above error this was not possible. So after stackoverflow search I found the above question. Inspired by an answer I changed the code like so:

private static final short[][] DataTable = new short[180][];
static {
    initializeA();
    initializeB();
}
private static void initializeA() {
    DataTable[0] = new short[]{32767,32767,32537,32260,31957};
    DataTable[1] = new short[]{14485,14441,14393,14338,14277,14210,14135,14052,13960};
    // Many more lines here ...
}
private static void initializeB() {
    DataTable[138] = new short[]{   60,   67,   75,   84,   95,  106,  119,  133};
    // Many more lines follow ...
}

The 2nd solution works but obviously there are some shortcomings:

  1. I had to know the number of rows and explicitly enumerate them
  2. It's much less neatly arranged in the source

Is there a more elegant way in Java to initialize the data?

Upvotes: 0

Views: 1840

Answers (2)

laune
laune

Reputation: 31290

I have tested this using 8000 ints and it compiles (Java 7 and 8).

static List<short[]> a = new ArrayList<>();
static void add( int... row ){
    short[] srow = new short[row.length];
    for(int i = 0; i < row.length; ++i ){ srow[i] = (short)row[i]; }
    a.add( srow );
}
static {
   add(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19);
   add(...)
}

You can take an short[][] from the List.

Although, using List<List<Integer>> shouldn't be a problem. An x.get(i,j) isn't much more inconvenient to write than a[i,j] - you just need a minimal class wrapper containing the list and the get method.

This also compiles:

static List<List<Integer>> a = new ArrayList<>();
static void add( Integer... row ){
     a.add( Arrays.asList( row ) );
}
static {
    add(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19);

For easy access, simply use

class TwoDim {
    static List<List<Integer>> a = ...
    static int get(int i, int j){ return a.get(i).get(j); }
}

Upvotes: 1

Uma Kanth
Uma Kanth

Reputation: 5629

Yes, there is.

Java ArrayList a dynamic array which grows in size as and when you add items. So the size? forget about it.

How do I use it in my case?

    ArrayList<Integer> list1 = new ArrayList(Arrays.asList(32767, 32767, 32537, 32260, 31957));
    ArrayList<Integer> list2 = new ArrayList(
            Arrays.asList(14485, 14441, 14393, 14338, 14277, 14210, 14135, 14052, 13960));

    System.out.println(list1 + " " + list1.size());
    System.out.println(list2 + " " + list2.size());

How to create a 2-Dimensional Array in an ArrayList.

There's a simple technique to do so.

Create an ArrayList() of type ArrayList()

ArrayList<Integer> list2 = new ArrayList(
            Arrays.asList(14485, 14441, 14393, 14338, 14277, 14210, 14135, 14052, 13960));
ArrayList<ArrayList<Integer>> myList = new ArrayList();
myList.add(list1);
myList.add(list2);

for (int i = 0; i < myList.size(); ++i)
    for (int j = 0; j < myList.get(i).size(); ++j)
        System.out.println(i + " " + j + " " + myList.get(i).get(j));

Upvotes: 1

Related Questions