SparseBooleanArray.equals () is not working properly

In the following code, I expect equals() return true , but it is not. What am I missing here?

  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 

Looking at both arrays in the debugger, they seem to be the same to me (they have a different shadow$_monitor_ , but I don't know what it should be). The toString() method returns the same string for both.

I am trying to write unit test for a function that converts EnumSet to a SparseBooleanArray , but I cannot create the same array manually to compare it with the return value of the function.


Edit

I should also note that hasCode() also returns different values, which shouldn't, based on the documentation .

+6
source share
1 answer

Looking at the source code, the equals and hashCode methods are not implemented for SparseBooleanArray , SparseIntArray , SparseLongArray and SparseArray . I would say that this is a critical missing feature and should be reported to Google.

In any case, I have been using these utilities for some time to solve this problem:

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

However, it is also possible (as indicated in the comments) and perhaps better to subclass the SparseArray class and override the equals and hashCode methods.

Disclaimer: I have not tested the implementation of hashCode or equals code below, please write some tests yourself to make sure that it works correctly. #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; } } 
0
source

Source: https://habr.com/ru/post/1013425/


All Articles