如何正确地将对象显示为String

时间:2010-10-16 16:18:54

标签: java tostring

我正在研究这段代码并希望打印一个矩阵,但那就是出现了什么 Matrix@2c78bc3b Matrix@2a8ddc4c

这是一个代码示例:

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));

    }
}

5 个答案:

答案 0 :(得分:7)

您需要以有意义的方式实施toString()

这个toString()(下面)可能适合调试,但如果你将它用于真正的用户输出,那将会很难看并且令人困惑。实际的解决方案可能会以某种复杂的方式使用Formatter来生成整齐的表格行和列。

基于您的代码的一些其他建议:

  • 建议不要分别存储行/列大小。 SSOT / Single Source of TruthDRYJava+DRY。只需使用.length,并在必要时提供访问者方法。
  • 在方法args中使用final,它将消除上面的错误,在构造函数中错误地别名numbers
  • 使用实例,而不是static
  • 偏执狂是程序员的生活方式:我还修改了我的代码以执行提供的deepCopy数组的int[][],否则会有参考泄漏,而Matrix类会如果调用者代码稍后修改了他们传入的int[][],则无法强制执行自己的不变量。

  • 我让Matrix不可变(见final private numbers[][])出于习惯。这是一个很好的做法,除非你提出了一个可变实现的充分理由(由于矩阵中的性能原因,这并不奇怪)。

以下是一些改进的代码:

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

答案 1 :(得分:4)

快速而肮脏的方法:

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

在不相关的注释中,变量rows,colms,numbers和方法isSquareMatrix不应声明为static。否则,当你得到一个转置时,你最终会得到两个写入相同类变量的矩阵对象。

答案 2 :(得分:2)

您没有为Matrix类定义toString方法,因此当您尝试打印Matrix时,您会看到默认toString方法的结果,该方法打印对象的类和唯一ID。

答案 3 :(得分:2)

System.out.print(Mat);

它将调用Matrix类的toString方法。

因此,如果要打印Matrix,则必须覆盖toString方法

@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";
}

答案 4 :(得分:2)

要在Matrix上显示print类对象,您必须在班级中定义toString方法。

代码中的另一个错误是,您没有设置rowscolms的值。所以当你这样做时

numbers = new int[rows][colms];

在您的构造函数中,rowscolms的默认值始终为0。你需要解决这个问题。然后,您必须将参数array中的矩阵元素复制到numbers