2016-12-22 4 views
6

다음 코드에서 equals()true을 반환하지만 예상하지는 않습니다. 내가 여기서 무엇을 놓치고 있니? 디버거에서 모두 배열을 보면 SparseBooleanArray.equals()가 예상대로 작동하지 않습니다.

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() 메서드는 둘 다 동일한 문자열을 반환합니다.

EnumSetSparseBooleanArray으로 변환하는 함수에 대한 단위 테스트를 작성하려하지만 동일한 배열을 수동으로 만들어 함수의 반환 값과 비교할 수는 없습니다.


편집

나는 또한 언급해야 그는 documentation에 따라 안뿐만 아니라 hasCode() 반환 다른 값.

+0

매우 이상합니다. 나는 당신의 결과를 재현 할 수 있지만 소스 코드는 그들이 일치해야하는 것처럼 보입니다 ... – CommonsWare

+1

어떤 버전의 안드로이드를 테스트하고 있습니까? – Blackbelt

+0

@Blackbelt on Android 6.0 API 23 - x86_64 에뮬레이터 – rozina

답변

0

소스 코드를 보면 모두 equalshashCode 방법은 SparseBooleanArray, SparseIntArray, SparseLongArraySparseArray 구현되지 않습니다. 중요한 기능이 없어서 Google에 신고해야합니다.

어쨌든, 나는이 문제를 해결하기 위해 꽤 많은 시간 동안 이러한 유틸리티 방법을 사용하십시오

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 메소드를 재정의하십시오.

면책 조항 : 나는 아래에 제공된 코드의 hashCode 또는 equals 구현을 테스트하지 않았다, 제대로 작동하는지 확인하기 위해 몇 가지 검사를 직접 작성하시기 바랍니다. #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; 
    } 
}