Как правильно отобразить объект в виде строки - PullRequest
4 голосов
/ 16 октября 2010

Я работаю над этим кодом и ожидаю, что матрица будет напечатана, но вот что получилось 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 ]

7 голосов
/ 16 октября 2010

Вам необходимо осмысленно реализовать toString().

Этот toString() (ниже), возможно, подходит для отладки, но будет уродливым и запутанным, если вы будете использовать его для реального пользовательского вывода.Фактическое решение, вероятно, будет использовать Formatter некоторым сложным способом для создания аккуратно табличных строк и столбцов.

Некоторые дополнительные рекомендации, основанные на вашем коде:

  • Предложите не хранить размеры строк / столбцов отдельно. SSOT / Единый источник истины или DRY , Java + DRY .Просто используйте .length и предоставьте методы доступа, если это необходимо.
  • Используйте final в аргументах метода, это устранит ошибки, как у вас выше, неверный псевдоним numbers внутри конструктора
  • Используйте экземпляр, а не static
  • Паранойя - это стиль жизни программиста: я также изменил свой код, чтобы сделать deepCopy из предоставленного массива int[][], в противном случае возникает утечка ссылок,и класс Matrix не сможет применить свои собственные инварианты, если код вызывающего абонента позже изменит int[][], который они передали.

  • Я сделал свой Matrix неизменным (см. * 1039).*) по привычке.Это хорошая практика, если только у вас нет веских причин для изменчивой реализации (это не удивительно для производительности в матрицах).

Вот несколько улучшенных кодов:

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());
  }
}
4 голосов
/ 16 октября 2010

для быстрого и грязного метода:

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

В несвязанной заметке строки переменных, столбцы, числа и методы isSquareMatrix не должны объявляться как статические.В противном случае, когда вы получите транспонирование, вы получите два матричных объекта, записывающих в одни и те же переменные класса.

2 голосов
/ 16 октября 2010

Чтобы отобразить объект класса Matrix, когда вы можете print, вы должны определить метод toString в вашем классе.

Еще одна ошибка в коде: вы не устанавливаете значения rows и colms. Итак, когда вы делаете

numbers = new int[rows][colms];

в вашем конструкторе, rows и colms всегда будут иметь значения по умолчанию 0. Вы должны это исправить. И тогда вам придется скопировать матричные элементы из параметра array в numbers.

2 голосов
/ 16 октября 2010
System.out.print(Mat);

вызовет метод 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";
}
2 голосов
/ 16 октября 2010

Вы не определили метод toString для своего класса Matrix, поэтому при попытке печати Matrix вы видите результат метода toString по умолчанию, который печатает класс объекта и уникальный идентификатор.

...