2016-12-22 24 views
6

W poniższym kodzie spodziewam się, że equals() zwróci true, ale tak się nie stanie. Czego tu mi brakuje?SparseBooleanArray.equals() nie działa zgodnie z oczekiwaniami

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 

Patrząc zarówno na tablicy w debugger, wydają się tak samo do mnie (mają inną wartość shadow$_monitor_, ale nie mam pojęcia, co to ma być). Metoda toString() zwraca ten sam ciąg również dla obu.

Próbuję napisać test jednostkowy dla funkcji, która konwertuje EnumSet na SparseBooleanArray, ale nie mogę ręcznie utworzyć tej samej tablicy, aby porównać ją z wartością zwracaną przez funkcję.


Edit

Należy również wspomnieć, że hasCode() zwraca różne wartości, a także, co nie powinno, na podstawie documentation.

+0

To jest bardzo dziwne. Mogę odtworzyć twoje odkrycia, ale kod źródłowy wygląda tak, jakby pasowały ... – CommonsWare

+1

na której wersji Androida testujesz? – Blackbelt

+0

@Blackbelt Na Androidzie 6.0 API 23 - emulator x86_64 – rozina

Odpowiedz

0

Patrząc na kod źródłowy zarówno metody equals i hashCode nie są realizowane za SparseBooleanArray, SparseIntArray, SparseLongArray i SparseArray. Powiedziałbym, że jest to bardzo ważna funkcja i należy ją zgłosić Google.

Zresztą używam od dłuższego czasu te metody narzędzie do rozwiązania tego problemu:

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

Jest jednak również możliwe (jak wspomniano w komentarzach), a być może lepiej, aby podklasy klasy SparseArray i zastąpić metody equals i hashCode.

Zastrzeżenie: Nie testowałem realizację kodu przewidzianego poniżej hashCode lub equals, napisz kilka testów siebie, aby upewnić się, że działa poprawnie. #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; 
    } 
} 
Powiązane problemy