У меня есть матричный объект, который я написал. Я предполагал, что матрица является неизменяемой как атрибут объекта, реализованного с помощью многомерного массива. как this.matrix
. Когда я называю матричные методы. он обязательно возвращает новый матричный объект, массив, который передается для создания объекта, должен быть глубоко скопирован.
Я провалю один тест в кодах, где ожидается двойное значение, отличное от значения, указанного при вызове метода toArray()
. но я не знаю никакой информации, так как код тестирования ограничен.
Может ли кто-нибудь увидеть в следующем коде, есть ли какие-либо точки, в которых я создал Матрицу, чей атрибут this.matrix
можно изменить извне самого объекта?
Я пытался использовать Arrays.copyOf
в конструкторе, чтобы убедиться, что новые объекты создаются для атрибута this.matrix
. Я убедился, чтобы вернуть новый объект Matrix для каждого метода. поэтому я не совсем понимаю, где еще можно случайно изменить переменную экземпляра this.matrix.
import java.util.Arrays;
@SuppressWarnings("WeakerAccess")
public class Matrix {
private double[][] matrix;
private int rows;
private int columns;
//constructor for the already sorted array
Matrix(double[][] elements) {
if (elements == null) {
throw new IllegalArgumentException("Elements cannot be null");
}
int columns = elements[0].length;
for(double[] element: elements){
if(element == null){
throw new IllegalArgumentException("Element of 2D Array cannot be null");
}
if(element.length != columns){
throw new IllegalArgumentException("Array rows are not of equal length");
}
}
this.matrix = elements;
this.rows = this.matrix.length;
this.columns = columns;
}
/// given row_length, row_column
/// given list of elements
Matrix(int rows, int columns, double... elements) {
// remember double ... elements means varargs
if(elements == null){
throw new IllegalArgumentException("Elements cannot be null");
}
if (elements.length != rows * columns) {
throw new IllegalArgumentException("Illegal number of rows and columns for elements given");
}
this.rows = rows;
this.columns = columns;
this.matrix = new double[this.rows][this.columns];
for(int i = 0; i<this.rows; i++){
// System.arraycopy(elements, i*columns, this.matrix[i], 0, columns);
double[] row = Arrays.copyOfRange(elements, i*columns, (i+1) * columns);
this.matrix[i] = Arrays.copyOf(row,columns);
}
}
public double[][] toArray() {
return this.matrix;
///prints out the array to string
}
public Matrix multiply(double scalar){
// this will just multiply the matrix with the scalar
double[][] result = new double[this.rows][this.columns];
for(int i = 0; i < this.matrix.length; i++){
for(int j = 0; j < this.matrix[0].length; j++){
result[i][j] = this.matrix[i][j] * scalar;
}
}
return new Matrix(result);
}
public Matrix multiply(Matrix right){
double[][] right_mat = right.toArray();
//assert that left n = right m
if(this.columns != right.rows){
throw new IllegalArgumentException("Left matrix columns is not equal to Right matrix rows");
}
double[][] result = new double[this.rows][right.columns];
//loop through twice and incrememnt the additions
for(int m = 0; m < this.rows; m++){
for(int k = 0; k < right.columns;k++){
for(int n = 0; n < right.rows; n++){
result[m][k] += this.matrix[m][n] * right_mat[n][k];
}
}
}
return new Matrix(result);
}
public Matrix transpose(){
double[][] result = new double[this.columns][this.rows];
for(int i = 0; i < this.matrix[0].length; i++){
final int column = i;
// new_row should be column of existing
double[] new_row = Arrays.stream(this.matrix).mapToDouble(doubles -> doubles[column]).toArray();
result[i] = new_row;
}
return new Matrix(result);
}
public Matrix add(Matrix b){
///takes in Matrix adds to this one and
///returns the resulting Matrix
if(this.columns != b.columns || this.rows != b.rows){
throw new IllegalArgumentException("Matrices are not the same shape");
}
double[][] b_matr = b.toArray();
double[][] result = new double[this.rows][this.columns];
///Matrix needs to have the same number of rows and columns
for(int i= 0; i < this.rows; i++){
for(int j = 0; j < this.columns; j++){
result[i][j] = this.matrix[i][j] + b_matr[i][j];
}
}
return new Matrix(result);
}
}