How to correctly display an object as a string

Im working on this code and expects the matrix to be printed, but here's what happened Matrix@2c78bc3b Matrix@2a8ddc4c

This is a sample code:

 public class Matrix { public static int rows; public static int colms;//columns public static int[][] numbers; public Matrix(int[][] numbers) { numbers = new int[rows][colms]; } public static boolean isSquareMatrix(Matrix m) { //rows = numbers.length; //colms = numbers[0].length; if(rows == colms) return true; else return false; } public static Matrix getTranspose(Matrix trans) { trans = new Matrix(numbers); for(int i =0; i < rows; i++) { for(int j = 0; j < colms; j++) { trans.numbers[i][j] = numbers[j][i]; } } return trans; } public static void main(String[] args) { int[][] m1 = new int[][]{{1,4}, {5,3}}; Matrix Mat = new Matrix(m1); System.out.print(Mat); System.out.print(getTranspose(Mat)); } } 
+4
source share
5 answers

You need to implement toString() meaningful way.

This toString() (below) may be suitable for debugging, but it will be ugly and confusing if you use it for real user output. The actual solution is likely to use Formatter some sophisticated way to create neatly table rows and columns.

Some additional recommendations based on your code:

  • Suggest not storing row / column sizes separately. SSOT / Single Source of Truth or DRY , Java + DRY . Just use .length and provide access methods if necessary.
  • Use final in method arguments, it will eliminate errors, as you above, aliasing numbers incorrect int constructor
  • Use instance, not static
  • Paranoia is a programmerโ€™s lifestyle: I also changed my code to make a deepCopy provided array int[][] , otherwise there is a leak link, and the Matrix class will not be able to execute its own if the caller code subsequently modified int[][] into which they went.

  • I made my Matrix immutable (see final private numbers[][] ) out of habit. This is good practice unless you have a good reason for a mutable implementation (not surprisingly for performance reasons in matrices).

Here are some improved codes:

 public final class Matrix { final private int[][] numbers; // note the final, which would find a bug in your cited code above... public Matrix(final int[][] numbers) { // by enforcing these assumptions / invariants here, you don't need to deal // with checking them in other parts of the code. This is long enough that you might // factor it out into a private void sanityCheck() method, which could be // applied elsewhere when there are non-trivial mutations of the internal state if (numbers == null || numbers.length == 0) throw new NullPointerException("Matrix can't have null contents or zero rows"); final int columns = numbers[0].length; if (columns == 0) throw new IllegalArgumentException("Matrix can't have zero columns"); for (int i =1; i < numbers.length; i++) { if (numbers[i] == null) throw new NullPointerException("Matrix can't have null row "+i); if (numbers[i].length != columns) throw new IllegalArgumentException("Matrix can't have differing row lengths!"); } this.numbers = deepCopy(numbers); } public boolean isSquareMatrix() { return rowCount() == columnCount(); } public int rowCount() { return numbers.length; } public int columnCount() {return numbers[0].length; } private static int[][] deepCopy(final int[][] source) { // note we ignore error cases that don't apply because of // invariants in the constructor: assert(source != null); assert(source.length != 0); assert(source[0] != null); assert(source[0].length != 0); int[][] target = new int[source.length][source[0].length]; for (int i = 0; i < source.length; i++) target[i] = Arrays.copyOf(source[i],source[i].length); return target; } public Matrix getTranspose() { int[][] trans = new int[columnCount()][rowCount()]; for (int i = 0; i < rowCount(); i++) for (int j = 0; j < columnCount(); j++) trans[i][j] = getValue(j, i); return new Matrix(trans); } @Override public String toString() { StringBuilder sb = new StringBuilder(); for (int i = 0; i < numbers.length; i++) { for (int j = 0; j < numbers[i].length; j++) sb.append(' ').append(numbers[i][j]); sb.append('\n'); } return sb.toString(); } public static void main(String[] args) { final int[][] m1 = new int[][] { { 1, 4 }, { 5, 3 } }; Matrix mat = new Matrix(m1); System.out.print(mat); System.out.print(mat.getTranspose()); } } 
+7
source

for a quick and dirty method:

 public String toString() { return Arrays.deepToString(numbers); } 

In an unrelated note, the variables rows, colms, numbers and isSquareMatrix methods should not be declared as static. Otherwise, when you get the transpose, you get two matrix objects that write the same class variables.

+4
source

You have not defined a toString method for your Matrix class, so when you try to print the matrix, you will see the result of the toString method by default, which prints the object's class and unique identifier.

+2
source
 System.out.print(Mat); 

it will call the toString method of the Matrix class.

So, if you want to print your matrix, you have to override the toString method

 @Override public String toString() { // create here a String representation of your matrix // ie: String myString = "1 0 0 1\n0 1 1 1\n..."; return "String representation of my matrix"; } 
+2
source

To display an object of the Matrix class, when you can print on it, you will need to define the toString method in your class.

Another error in the code: you do not set the value of rows and colms . Therefore when you do

 numbers = new int[rows][colms]; 

in your constructor rows and colms will always have a default value of 0 . You need to fix it. And then you have to copy the matrix elements from the array parameter to numbers .

+2
source

All Articles