Skip to main content
replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link
URL Rewriter Bot
URL Rewriter Bot
  • Suggest not storing the rows/columns sizes separately. SSOT / Single Source of Truth or DRY, Java+DRYJava+DRY. Just use the .length, and provide accessor methods if need be.

  • Use final in method args, it will eliminate bugs like you have above, aliasing numbers incorrectly int the constructor

  • Use an instance, not static

  • Paranoia is the programmer's lifestyle: I also modified my code to do a deepCopy of the provided int[][] array, otherwise there is reference leakage, and the Matrix class would be unable to enforce its own invariants if caller code later modified the int[][] they passed in.

  • I made my Matrix immutable (see final private numbers[][]) out of habit. This is a good practice, unless you come up with a good reason for a mutable implementation (wouldn't be surprising for performance reasons in matrices).

  • Suggest not storing the rows/columns sizes separately. SSOT / Single Source of Truth or DRY, Java+DRY. Just use the .length, and provide accessor methods if need be.

  • Use final in method args, it will eliminate bugs like you have above, aliasing numbers incorrectly int the constructor

  • Use an instance, not static

  • Paranoia is the programmer's lifestyle: I also modified my code to do a deepCopy of the provided int[][] array, otherwise there is reference leakage, and the Matrix class would be unable to enforce its own invariants if caller code later modified the int[][] they passed in.

  • I made my Matrix immutable (see final private numbers[][]) out of habit. This is a good practice, unless you come up with a good reason for a mutable implementation (wouldn't be surprising for performance reasons in matrices).

  • Suggest not storing the rows/columns sizes separately. SSOT / Single Source of Truth or DRY, Java+DRY. Just use the .length, and provide accessor methods if need be.

  • Use final in method args, it will eliminate bugs like you have above, aliasing numbers incorrectly int the constructor

  • Use an instance, not static

  • Paranoia is the programmer's lifestyle: I also modified my code to do a deepCopy of the provided int[][] array, otherwise there is reference leakage, and the Matrix class would be unable to enforce its own invariants if caller code later modified the int[][] they passed in.

  • I made my Matrix immutable (see final private numbers[][]) out of habit. This is a good practice, unless you come up with a good reason for a mutable implementation (wouldn't be surprising for performance reasons in matrices).

immutable; Post Made Community Wiki
Source Link
andersoj
  • 23.1k
  • 7
  • 64
  • 74
  • Suggest not storing the rows/columns sizes separately. SSOT / Single Source of Truth or DRY, Java+DRY. Just use the .length, and provide accessor methods if need be.

    Suggest not storing the rows/columns sizes separately. SSOT / Single Source of Truth or DRY, Java+DRY. Just use the .length, and provide accessor methods if need be.

  • Use final in method args, it will eliminate bugs like you have above, aliasing numbers incorrectly int the constructor

    Use final in method args, it will eliminate bugs like you have above, aliasing numbers incorrectly int the constructor

  • Use an instance, not static

    Use an instance, not static

  • Paranoia is the programmer's lifestyle: I also modified my code to do a deepCopy of the provided int[][] array, otherwise there is reference leakage, and the Matrix class would be unable to enforce its own invariants if caller code later modified the int[][] they passed in.

    Paranoia is the programmer's lifestyle: I also modified my code to do a deepCopy of the provided int[][] array, otherwise there is reference leakage, and the Matrix class would be unable to enforce its own invariants if caller code later modified the int[][] they passed in.

  • I made my Matrix immutable (see final private numbers[][]) out of habit. This is a good practice, unless you come up with a good reason for a mutable implementation (wouldn't be surprising for performance reasons in matrices).

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()); } } 
  • Suggest not storing the rows/columns sizes separately. SSOT / Single Source of Truth or DRY, Java+DRY. Just use the .length, and provide accessor methods if need be.
  • Use final in method args, it will eliminate bugs like you have above, aliasing numbers incorrectly int the constructor
  • Use an instance, not static
  • Paranoia is the programmer's lifestyle: I also modified my code to do a deepCopy of the provided int[][] array, otherwise there is reference leakage, and the Matrix class would be unable to enforce its own invariants if caller code later modified the int[][] they passed in.
public final class Matrix { 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()); } } 
  • Suggest not storing the rows/columns sizes separately. SSOT / Single Source of Truth or DRY, Java+DRY. Just use the .length, and provide accessor methods if need be.

  • Use final in method args, it will eliminate bugs like you have above, aliasing numbers incorrectly int the constructor

  • Use an instance, not static

  • Paranoia is the programmer's lifestyle: I also modified my code to do a deepCopy of the provided int[][] array, otherwise there is reference leakage, and the Matrix class would be unable to enforce its own invariants if caller code later modified the int[][] they passed in.

  • I made my Matrix immutable (see final private numbers[][]) out of habit. This is a good practice, unless you come up with a good reason for a mutable implementation (wouldn't be surprising for performance reasons in matrices).

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()); } } 
consolidate code
Source Link
andersoj
  • 23.1k
  • 7
  • 64
  • 74

You need to implement toString() in a meaningful way. For (untested) example:

@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(); } 

This toString() (below) is perhaps suitable for debugging, but will be ugly and confusing if you use it for real user output. An actual solution would probably use a Formatter in some complicated way to produce neatly tabular rows and columns.

public final class Matrix { 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()); } } 

You need to implement toString() in a meaningful way. For (untested) example:

@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(); } 

This toString() is perhaps suitable for debugging, but will be ugly and confusing if you use it for real user output. An actual solution would probably use a Formatter in some complicated way to produce neatly tabular rows and columns.

public final class Matrix { 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); } 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()); } } 

You need to implement toString() in a meaningful way.

This toString() (below) is perhaps suitable for debugging, but will be ugly and confusing if you use it for real user output. An actual solution would probably use a Formatter in some complicated way to produce neatly tabular rows and columns.

public final class Matrix { 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()); } } 
properly oo'ified
Source Link
andersoj
  • 23.1k
  • 7
  • 64
  • 74
Loading
paranoia
Source Link
andersoj
  • 23.1k
  • 7
  • 64
  • 74
Loading
comments in code
Source Link
andersoj
  • 23.1k
  • 7
  • 64
  • 74
Loading
More corner cases.
Source Link
andersoj
  • 23.1k
  • 7
  • 64
  • 74
Loading
formatting cleanup
Source Link
andersoj
  • 23.1k
  • 7
  • 64
  • 74
Loading
formatting
Source Link
andersoj
  • 23.1k
  • 7
  • 64
  • 74
Loading
formatting
Source Link
andersoj
  • 23.1k
  • 7
  • 64
  • 74
Loading
formatting
Source Link
andersoj
  • 23.1k
  • 7
  • 64
  • 74
Loading
link Formatter
Source Link
andersoj
  • 23.1k
  • 7
  • 64
  • 74
Loading
Source Link
andersoj
  • 23.1k
  • 7
  • 64
  • 74
Loading