Home > OS >  Writing a toString method for 2D arrays
Writing a toString method for 2D arrays

Time:08-30

I have some code for a 2D array but I don't want spaces at the end of each row before I start a new row. For some reason, I can't find where I'm messing up because a space is being put at the end of each row. Basically what I'm trying to do is input a 2D array and the output should make it look the same as the input, except for the {}'s and it'll be a string. For example,

Input:

{1, 2, 3}, {4, 5, 6};

Output:

1 2 3

4 5 6

public class Matrix {

// the dimensions of the matrix
private int numRows;
private int numColumns;

// the internal storage for the matrix elements 
private int data[][];

/**
 * @param d - the raw 2D array containing the initial values for the Matrix.
 */
public Matrix(int d[][])
{
    // d.length is the number of 1D arrays in the 2D array
    numRows = d.length; 
    if(numRows == 0)
        numColumns = 0;
    else
        numColumns = d[0].length; // d[0] is the first 1D array
    
    // create a new matrix to hold the data
    data = new int[numRows][numColumns]; 
    
    // copy the data over
    for(int i=0; i < numRows; i  ) 
        for(int j=0; j < numColumns; j  )
            data[i][j] = d[i][j];
}

/**
 * Returns a String representation of this Matrix.
 */
@Override // instruct the compiler that we intend for this method to override the superclass' (Object) version
public String toString() {
    
    // TODO: replace the below return statement with the correct code.
    String arrString = "";
    for(int i = 0; i < data.length; i  ) {
        for(int j = 0; j < data[i].length; j  ) {
            arrString  = data[i][j]   " ";
        }
        arrString  = "\n";
    }
    return arrString;
    
}

CodePudding user response:

Next time please post a runnable example.

Your problem was that you always added a space after the item, no matter if it was the last one in the line. I now check that with a conditional (j == data[i].length - 1 ? "" : " ");

Hint: It's not good to concatenate Strings. Use StringBuilder for better performance an memory usage. I added a second method toString2() to show how it's done.

package stackoverflow;

public class Matrix {

    // the dimensions of the matrix
    private final int   numRows;
    private int         numColumns;

    // the internal storage for the matrix elements
    private final int data[][];

    /**
     * @param d - the raw 2D array containing the initial values for the Matrix.
     */
    public Matrix(final int d[][]) {
        // d.length is the number of 1D arrays in the 2D array
        numRows = d.length;
        if (numRows == 0)
            numColumns = 0;
        else
            numColumns = d[0].length; // d[0] is the first 1D array

        // create a new matrix to hold the data
        data = new int[numRows][numColumns];

        // copy the data over
        for (int i = 0; i < numRows; i  )
            for (int j = 0; j < numColumns; j  )
                data[i][j] = d[i][j];
    }

    /**
     * Returns a String representation of this Matrix.
     */
    @Override // instruct the compiler that we intend for this method to override the superclass' (Object) version
    public String toString() {

        // TODO: replace the below return statement with the correct code.
        String arrString = "";
        for (int i = 0; i < data.length; i  ) {
            for (int j = 0; j < data[i].length; j  ) {
                arrString  = data[i][j]   (j == data[i].length - 1 ? "" : " ");
            }
            arrString  = "\n";
        }
        return arrString;

    }

    public String toString2() {
        final StringBuilder sb = new StringBuilder();
        for (int i = 0; i < data.length; i  ) {
            for (int j = 0; j < data[i].length; j  ) {
                sb.append(data[i][j]   (j == data[i].length - 1 ? "" : " "));
            }
            sb.append("\n");
        }
        return sb.toString();
    }



    public static void main(final String[] args) {
        final int[][] arr = new int[2][3];
        arr[0][0] = 4;
        arr[0][1] = 6;
        arr[0][2] = 8;
        arr[1][0] = 8;
        arr[1][1] = 16;
        arr[1][2] = 23;
        final Matrix m = new Matrix(arr);
        System.out.println("Matrix:\n"   m);
        System.out.println("Matrix 2:\n"   m.toString2());
    }



}

Output:

Matrix:
4 6 8
8 16 23

Matrix 2:
4 6 8
8 16 23

CodePudding user response:

The Answer by JayC667 seems to correctly address your Question.

Stream, lambda, & method reference

For fun, here is an alternative approach using stream, lambda, and method reference.

Define the array.

int[][] input = { { 1 , 2 , 3 } , { 4 , 5 , 6 } };  // Declaration, initialization.

Make a stream where each element is a row, an array of int values, from your two-dimensional array.

For each of those rows, each being a int[], make a stream of its int primitive values (an IntStream), convert each primitive to an Integer object (boxing), call each Integer object’s toString method to generate a piece of text. Collect those pieces of text by joining them into a longer String with a SPACE character as a delimiter.

So we have transformed each row into a String. Collect all those strings together, with a LINE FEED character as the delimiter. Then, we are done, with a single String object as a result.

All that work, in a single line of code!

String result =
        Arrays
                .stream( input )                         // A series of integer arrays, etc element being a int[]. 
                .map(                                    // Convert each integer array into something else, a `String` object. 
                        ( int[] row ) -> Arrays.stream( row ).boxed().map( Object :: toString ).collect( Collectors.joining( " " ) )
                )
                .collect( Collectors.joining( "\n" ) );  // Join each row of text with the next, using Linefeed as delimiter.

Results.

1 2 3
4 5 6

CodePudding user response:

Here is one way to return a formatted 2D array based on the anticipated width of the values.

  • %nd - specifies a field width of n digits, right aligned.
  • %-nd - specifies a field width of n digits, left aligned (would have spaces at end of line).
  • fields will be filled in with spaces where necessary.
public class TwoDtoString {
    
    int[][] mat = { { 11, 222, 3333 }, { 433, 53, 633 }, { 73, 8, 9333 } };
    static String FORMAT = "]"; // 5 digit field, right aligned.
    public static void main(String[] args) {
        TwoDtoString tos = new TwoDtoString();
        System.out.println(tos.toString());
    }
    
    public String toString() {
        StringBuilder sb = new StringBuilder();
        for (int[] row : mat) {
            sb.append(FORMAT.formatted(row[0]));
            for (int i = 1; i < row.length; i  ) {
                sb.append(FORMAT.formatted(row[i]));
            } 
            sb.append("\n");
        }
        return sb.toString();
    }   
}

prints

   11  222 3333
  433   53  633
   73    8 9333

  • Related