Save space occupied by 2D array My goal is to save space occupied by 2D array (sea) that has 3 different values.

Ocean sea; //Ocean class has member 'private int[][] oceanMatrix;'

public final static int EMPTY = 1;
public final static int SHARK = 2;
public final static int FISH = 3;


by compressing it and place in two one dimensional array.

int[] runType = new int[10]; // each cell stores 1 or 2 or 3

int[] runLength = new int[10]; // corresponding index cell stores its number of occurence of that respective runType.


I am using Runlength encoding idea and wrote below code, which is yet to be fit into a Java class.

I need feedback/critiques on this logic of the below code and coding style, so that I can optimize and make it better. Constraint is to not use any existing Java library class except (array's length member).

private static int[] doubleTheSize(int[] arg){
        int[] temp = new int[2*arg.length];
        for(int c = 0; c &lt; arg.length; c++){
            temp[c] = arg[c];
        }
        return temp;
    }

public static void main(String[] args) {
            Ocean sea;
            int[] runType = new int[10];
        int[] runLength = new int[10];
        int index = 0;
        boolean firstCell = true;
 //i&amp;j are width &amp; height of a 2d array read from commandline
        for(int row = 0; row &lt; j ; row++){
            for(int col = 0; col &lt; i ; col++){
                if(firstCell){
                    firstCell=false;
                    runType[index] = sea.cellContents(0, 0);
                    runLength[index]++;
                    continue;
                }
                switch(sea.cellContents(row, col)){
                case Ocean.EMPTY:
                    if(runType[index] == Ocean.EMPTY){
                        runLength[index]++;
                    }else{
                        index++;
                        if(index==runType.length){
                            runType = doubleTheSize(runType);
                            runLength = doubleTheSize(runLength);
                        }
                        runType[index]=Ocean.SHARK;
                        runLength[index]++;
                    }
                    break;
                case Ocean.SHARK:
                    if(runType[index] == Ocean.SHARK){
                        runLength[index]++;
                    }else{
                        index++;
                        if(index==runType.length){
                            runType = doubleTheSize(runType);
                            runLength = doubleTheSize(runLength);
                        }
                        runType[index]=Ocean.SHARK;
                        runLength[index]++;
                    }
                    break;  
                case Ocean.FISH:
                    if(runType[index] == Ocean.FISH){
                        runLength[index]++;
                    }else{
                        index++;
                        if(index==runType.length){
                            runType = doubleTheSize(runType);
                            runLength = doubleTheSize(runLength);
                        }
                        runType[index]=Ocean.FISH;
                        runLength[index]++;
                    }
                    break;
                }// end switch
            }//end inner for loop
        }//end outer for loop
}//end main()


I wrote the above code for that.  Please help me review this code for optimization. One point that I recognized is, firstCell check that I did for every cell doesn't make sense. I need suggestion to better this logic because I need to enter in firstCell i{} block for only (0,0) cell.
A few notes about the original code.


If the ocean mostly empty it's actually a sparse matrix. If you are allowed to use more arrays or another primitive data structures check the Spare matrix Wikipedia article about it, it contains other, maybe more effective storage structures.
The second switch case contains the same logic three times. You could extract it out to a method to remove duplication:

private static int encode(int[] runType, int[] runLength, int currentType, int index) {
    if (runType[index] == currentType) {
        runLength[index]++;
    } else {
        index++;
        if (index == runType.length) {
            runType = doubleTheSize(runType);
            runLength = doubleTheSize(runLength);
        }
        runType[index] = currentType;
        runLength[index]++;
    }
    return index;
}


And use it in the switch:

switch (sea.cellContents(row, col)) {
case Ocean.EMPTY: {
    final int currentType = Ocean.EMPTY;
    index = encode(runType, runLength, currentType, index);
    break;
}
case Ocean.SHARK: {
    int currentType = Ocean.SHARK;
    index = encode(runType, runLength, currentType, index);
    break;
}
case Ocean.FISH: {
    int currentType = Ocean.FISH;
    index = encode(runType, runLength, currentType, index);
    break;
}


After that it's easier to notice that the whole switch-case could be eliminated since the body of every case statement is very similar to each other and depends on only the sea.cellContents(row, col) value.

final int currentType = sea.cellContents(row, col);
index = encode(runType, runLength, currentType, index);



int[] runLength = new int[10]; // corresponding index cell stores its number of occurence of that respective runType.


I'd put the comment before the line it comments:

// corresponding index cell stores its number of occurrence of that respective runType.
int[] runLength = new int[10];


It's easier to work with because it requires less horizontal scrolling.
A comment says the following:

// i&amp;j are width &amp; height of a 2d array read from commandline


Then you can use width and height as variable names for better readabilty (you don't have to remember what i or j mean nor check the comment for it) and could get rid of the comment.
The temp variable in doubleTheSize could be called doubledArray or newArray, arg is oldArray or originalArray. It would express the purpose of them.
Comments on the closing curly braces are unnecessary and disturbing. Modern IDEs could show blocks.

    }// end outer for loop
}// end main()


“// …” comments at end of code block after } - good or bad?