简体   繁体   English

2D Arrays 和矩阵 - Java

[英]2D Arrays & Matrices - Java

I have to admit, I'm a little stuck on this equals method.我不得不承认,我有点坚持这种 equals 方法。 I think I'm pretty close because the first JUnit test that we're given passes but when I make a test for one that should return false, I fail and it returns true.我想我已经很接近了,因为我们获得的第一个 JUnit 测试通过了,但是当我对一个应该返回 false 的测试进行测试时,我失败了,它返回 true。 Can I get some assistance on this, please?请问我可以在这方面得到一些帮助吗?

public class Matrix {

// the dimensions of the matrix
private int numRows;
private int numColumns;

// the internal storage for the matrix elements 
private int data[][];

/**
 * @param d - the raw 2D array containing the initial values for the Matrix.
 */
public Matrix(int d[][])
{
    // d.length is the number of 1D arrays in the 2D array
    numRows = d.length; 
    if(numRows == 0)
        numColumns = 0;
    else
        numColumns = d[0].length; // d[0] is the first 1D array
    
    // create a new matrix to hold the data
    data = new int[numRows][numColumns]; 
    
    // copy the data over
    for(int i=0; i < numRows; i++) 
        for(int j=0; j < numColumns; j++)
            data[i][j] = d[i][j];
}



/**
 * Determines whether this Matrix is equal to another object.
 * @param o - the other object to compare to, which may not be a Matrix
 */
@Override // instruct the compiler that we intend for this method to override the superclass' (Object) version
public boolean equals(Object o)
{
    // make sure the Object we're comparing to is a Matrix
    if(!(o instanceof Matrix))
        return false;
    
    // if the above was not true, we know it's safe to treat 'o' as a Matrix
    Matrix m = (Matrix)o;
    
    /*
     * TODO: replace the below return statement with the correct code. 
     *  
     *  Returns true if this Matrix is equal to the input Matrix; returns false otherwise
     */ 
    boolean matches = true;
    
    if(o instanceof Matrix)
        for(int i = 0; i < data[i].length; i++)
            for(int j = 0; j < data[j].length; j++)
                if(o[i][j] != m[i][j])
                    matches = false;
    
    return matches;
}

The problem is here:问题在这里:

if(o instanceof Matrix)
    for(int i = 0; i < data[i].length; i++)
        for(int j = 0; i < data[j].length; j++)
            if(o[i][j] == m[i][j])
                return true;

You're looping over every element in the array and when you found any element that matches with the element in the other array, you're returning true .您正在遍历数组中的每个元素,当您找到与另一个数组中的元素匹配的任何元素时,您将返回true I would create a boolean (initially set to true ) and when I found an element that doesn't match, I would set the boolean to false and return the boolean at the end of the method:我将创建一个boolean (最初设置为true ),当我发现一个不匹配的元素时,我会将boolean设置为false并在方法的末尾返回boolean

boolean matches = true;

if(o instanceof Matrix)
    for(int i = 0; i < data[i].length; i++)
        for(int j = 0; i < data[j].length; j++)
            if(o[i][j] != m[i][j])
                matches = false;

return matches;

This author asked nearly the same question .这位作者问了几乎相同的问题 To simplify things, I'll answer here instead of there.为了简化事情,我将在这里而不是那里回答。

If I were a teacher, these are the things I would point out, step-by-step:如果我是老师,这些是我会一步一步指出的事情:

  1. This won't compile: if(o[i][j] != m[i][j]) Neither o nor m is an array, and so can't have subscripts.这不会编译: if(o[i][j] != m[i][j]) om都不是数组,因此不能有下标。

  2. Suppose we make this change: if (o.data[i][j].= m.data[i][j]) .假设我们做出这样的改变: if (o.data[i][j].= m.data[i][j]) Now o.data[i][j] won't compile, because o is an Object type, which has no member named data .现在o.data[i][j]不会编译,因为o是一个Object类型,它没有名为data的成员。

  3. We could use a class cast like this: if (((Matrix) o).data[i][j].= m.data[i][j]) .我们可以像这样使用 class 演员表: if (((Matrix) o).data[i][j].= m.data[i][j]) Now, it will compile.现在,它将编译。 But, the code above has this line: Matrix m = (Matrix)o;但是,上面的代码有这一行: Matrix m = (Matrix)o; So, o and m point to the same object .所以, om指向同一个 object As long as that's the case, ((Matrix) o).data[i][j] == m.data[i][j] will always be true .只要是这样, ((Matrix) o).data[i][j] == m.data[i][j]永远是true

  4. To fix the above, we need to use two different instances of Matrix .要解决上述问题,我们需要使用Matrix的两个不同实例。 We get one instance from the parameter: o .我们从参数中得到一个实例: o The second one is implicit, but has a name: this .第二个是隐含的,但有一个名字: this So, this is what we want for our comparison: if(this.data[i][j].= m.data[i][j])所以,这就是我们想要的比较: if(this.data[i][j].= m.data[i][j])

Here are some other comments, outside the scope of your question:以下是您问题的 scope 之外的其他一些评论:

Once you have determined that the contents of the two instances of Matrix do not match, you can escape the for loops with break .一旦确定Matrix的两个实例的内容不匹配,就可以使用break转义for循环。 It could save time if you are processing large matrices.如果您正在处理大型矩阵,它可以节省时间。

@Override
public boolean equals (Object o) {
    if (o == this) return true;
    if (o == null) return false;
    if(!(o instanceof Matrix)) return false;
    

In general, it is a good idea to begin .equals methods with the above 3 tests.一般而言,从上述 3 个测试开始.equals方法是一个好主意。

     Matrix m = (Matrix)o;  
    

When overriding .equals , it's strongly recommended that hascode () be overridden also.当覆盖.equals时,强烈建议也覆盖hascode () So, please think about the following line:因此,请考虑以下行:

    if (m.hashCode() != this.hashCode()) return false;

If hashcode () is properly implemented, two objects returning different hash codes are guaranteed to return false for .equals .如果hashcode ()被正确实现,返回不同 hash 代码的两个对象保证为.equals返回false However, two objects returning the same hash code could return either true or false for .equals .但是,返回相同.equals代码的两个对象对于 .equals 可能返回truefalse So, if the hascode() test returns true, we keep testing:所以,如果hascode()测试返回 true,我们继续测试:

// two matrices can have different sizes. Comparing the sizes early
// will not only save time, it  will guard against throwing 
// an `ArrayIndexOutOfBoundsException` when the sizes are different

if (    m.numRows    != this.numRows 
     || m.numColumns != this.numColumns) return false;

 boolean matches = true;

 outer: for(int i = 0; i < numRows; i++) {
           for(int j = 0; numColumns; j++) {
               if(this.data[i][j] != m.data[i][j]) {
                  matches = false;
                  if (!matches)
                    break outer;
            }
        }            
    }        
return matches;

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM