SparseBooleanArray.equals()无法按预期工作

roz*_*ina 6 java android sparse-matrix

在下面的代码中我希望equals()返回true,但事实并非如此.我在这里错过了什么?

    SparseBooleanArray array_0 = new SparseBooleanArray();
    array_0.put(0, true);
    array_0.put(2, true);

    SparseBooleanArray array_1 = new SparseBooleanArray();
    array_1.put(0, true);
    array_1.put(2, true);

    boolean isEqual = array_0.equals(array_1); // is false instead of true
Run Code Online (Sandbox Code Playgroud)

在调试器中查看两个数组,它们对我来说似乎是一样的(它们有不同的shadow$_monitor_值,但我不知道应该是什么).该toString()方法也为两者返回相同的字符串.

我想写的一种转换功能单元测试EnumSetSparseBooleanArray,但我不能手动创建同一阵列将其与函数的返回值进行比较.


编辑

我还应该提一下hasCode(),根据文档,也不应该返回不同的值.

Rol*_*f ツ 0

查看源代码,equals和方法都hashCode没有针对SparseBooleanArraySparseIntArray和实现。我想说这是一个关键的缺失功能,应该向谷歌报告。SparseLongArraySparseArray

无论如何,我使用了相当长一段时间这些实用方法来解决这个问题:

public static boolean equals(SparseArray arrayOne, SparseArray arrayTwo){
    if(arrayOne == arrayTwo){
        return true;
    } else if(arrayOne.size() != arrayTwo.size()){
        return false;
    }
    for(int i = 0; i < arrayOne.size(); i++){
        if(arrayOne.keyAt(i) != arrayTwo.keyAt(i)){
            return false;
        }
        final Object valueOne = arrayOne.valueAt(i);
        final Object valueTwo = arrayTwo.valueAt(i);
        if(valueOne != null && !valueOne.equals(valueTwo)){
            return false;
        } else if(valueTwo != null && !valueTwo.equals(valueOne)){
            return false;
        }
    }
    return true;
}

public static boolean equals(SparseBooleanArray arrayOne, SparseBooleanArray arrayTwo){
    if(arrayOne == arrayTwo){
        return true;
    } else if(arrayOne.size() != arrayTwo.size()){
        return false;
    }
    for(int i = 0; i < arrayOne.size(); i++){
        if(arrayOne.keyAt(i) != arrayTwo.keyAt(i)){
            return false;
        } else if(arrayOne.valueAt(i) != arrayTwo.valueAt(i)){
            return false;
        }
    }
    return true;
}

public static boolean equals(SparseIntArray arrayOne, SparseIntArray arrayTwo){
    if(arrayOne == arrayTwo){
        return true;
    } else if(arrayOne.size() != arrayTwo.size()){
        return false;
    }
    for(int i = 0; i < arrayOne.size(); i++){
        if(arrayOne.keyAt(i) != arrayTwo.keyAt(i)){
            return false;
        } else if(arrayOne.valueAt(i) != arrayTwo.valueAt(i)){
            return false;
        }
    }
    return true;
}

@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public static boolean equals(SparseLongArray arrayOne, SparseLongArray arrayTwo){
    if(arrayOne == arrayTwo){
        return true;
    } else if(arrayOne.size() != arrayTwo.size()){
        return false;
    }
    for(int i = 0; i < arrayOne.size(); i++){
        if(arrayOne.keyAt(i) != arrayTwo.keyAt(i)){
            return false;
        } else if(arrayOne.valueAt(i) != arrayTwo.valueAt(i)){
            return false;
        }
    }
    return true;
}
Run Code Online (Sandbox Code Playgroud)

然而,也可以(如评论中提到的),并且可能更好,SparseArray子类化该类并重写equalshashCode方法。

免责声明:我没有测试下面提供的代码hashCodeequals实现,请自己编写一些测试以确保其正常工作。#不要信任互联网

public class SparseBooleanArray extends android.util.SparseBooleanArray {

    @Override
    public boolean equals(Object o) {
        if(!(o instanceof SparseBooleanArray)){
            return false;
        } else if(this == o){
            return true;
        }
        final SparseBooleanArray other = (SparseBooleanArray) o;
        if(size() != other.size()){
            return false;
        }
        for(int i = 0; i < size(); i++){
            if(keyAt(i) != other.keyAt(i)){
                return false;
            } else if(valueAt(i) != other.valueAt(i)){
                return false;
            }
        }
        return true;
    }

    @Override
    public int hashCode() {
        int result = 17;
        for(int i = 0; i < size(); i++){
            result = 31 * result + keyAt(i);
            result = 31 * result + (valueAt(i)?1:0);
        }
        return result;
    }
}
Run Code Online (Sandbox Code Playgroud)