javaarraylisttranspose

Transpose ArrayList<ArrayList<String>> in Java


I have a method attempting to transpose a ArrayList containing an ArrayList of string, called matrix and return the new array.

I found Transposing Values in Java 2D ArrayList, but it looks like it's for Arrays and not ArrayLists. My 2D array is of unknown dimensions, either rectangular or possibly irregular (but never square).

My idea was to read each inner array, and append the items to the inner arrays of the outgoing matrix.

public static ArrayList<ArrayList<String>> transpose (ArrayList<ArrayList<String>> matrixIn){
    ArrayList<ArrayList<String>> matrixOut = new ArrayList<>();
    //for each row in matrix
    for (int r = 0; r < matrixIn.size(); r++){
        ArrayList<String> innerIn = matrixIn.get(r);

        //for each item in that row
        for (int c = 0; c < innerIn.size(); c++){

            //add it to the outgoing matrix

            //get matrixOut current value
            ArrayList<String> matrixOutRow = matrixOut.get(c);
            //add new one
            matrixOutRow.add(innerIn.get(c));
            //reset to matrixOut
            matrixOut.set(c,matrixOutRow);
        }
    }
    return matrixOut;
}

I'm getting an "IndexOutOfBoundsException: Index: 0, Size: 0" error at

        //get matrixOut[v]
        ArrayList<String> matrixOutRow = matrixOut.get(v);

What am I doing wrong with this thing?


Solution

  • Answering my own question here. This is what I'm now doing:

        public static ArrayList<ArrayList<String>> transpose (ArrayList<ArrayList<String>> matrixIn){
        ArrayList<ArrayList<String>> matrixOut = new ArrayList<>();
        int rowCount = matrixIn.size();
        int colCount = 0;
    
        //find max width
        for(int i = 0; i < rowCount; i++){
            ArrayList<String> row = matrixIn.get(i);
            int rowSize = row.size();
            if(rowSize > colCount){
                colCount = rowSize;
            }
        }
        //for each row in matrix
        for (int r = 0; r < rowCount; r++){
            ArrayList<String> innerIn = matrixIn.get(r);
    
            //for each item in that row
            for (int c = 0; c < colCount; c++){
    
                //add it to the outgoing matrix
                //get matrixOut[c], or create it
                ArrayList<String> matrixOutRow = new ArrayList<>();
                if (r != 0) {
                    try{
                        matrixOutRow = matrixOut.get(c);
                    }catch(java.lang.IndexOutOfBoundsException e){
                        System.out.println("Transposition error!\n"
                                + "could not get matrixOut at index "
                                 + c + " - out of bounds" +e);
                        matrixOutRow.add("");
                    }
                }
                //add innerIn[c]
                try{
                    matrixOutRow.add(innerIn.get(c));
                }catch (java.lang.IndexOutOfBoundsException e){
                    matrixOutRow.add("");
                }
    
                //reset to matrixOut[c]
                try {
                    matrixOut.set(c,matrixOutRow);                
                }catch(java.lang.IndexOutOfBoundsException e){
                    matrixOut.add(matrixOutRow);
                }
            }
        }
        return matrixOut;
    }
    

    I can't assume smooth arrays and I want to still return a nested ArrayList. So now I'm just finding the maximum dimensions and catching all of the out of bounds errors by adding "".

    I'm sure there's a cleaner way, but this seems to be working.