簡體   English   中英

SparseBooleanArray.equals()無法按預期工作

[英]SparseBooleanArray.equals() not working as expected

在下面的代碼中,我希望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

在調試器中查看這兩個數組,它們對我來說似乎是一樣的(它們有一個不同的shadow$_monitor_值,但我不知道應該是什么)。 toString()方法也為兩者返回相同的字符串。

我正在嘗試為將EnumSet轉換為SparseBooleanArray的函數編寫單元測試,但我無法手動創建相同的數組以將其與函數的返回值進行比較。


編輯

我還應該提一下, hasCode()也會返回不同的值,根據文檔 ,它不應該返回。

查看源代碼,對於SparseBooleanArraySparseIntArraySparseLongArraySparseArray ,都沒有實現equalshashCode方法。 我會說這是一個關鍵的缺失功能,應該報告給谷歌。

無論如何,我使用這些實用方法已經有一段時間來解決這個問題了:

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

但是,也可以(如注釋中所述),並且可能更好,子類化SparseArray類並覆蓋equalshashCode方法。

免責聲明:我沒有測試hashCodeequals下面提供的代碼的實現,請自己編寫一些測試以確保它正常工作。 #DontTrustTheInternet

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM