ArrayList의 contains () 메소드는 객체를 어떻게 평가합니까?


303

하나의 객체를 만들어 내에 추가한다고 가정 해보십시오 ArrayList. 그런 다음 정확히 동일한 생성자 입력으로 다른 객체를 만들면 contains()메소드가 두 객체가 동일한 것으로 평가합니까? 생성자가 입력에 대해 재미있는 작업을 수행하지 않고 두 객체에 저장된 변수가 동일하다고 가정하십시오.

ArrayList<Thing> basket = new ArrayList<Thing>();  
Thing thing = new Thing(100);  
basket.add(thing);  
Thing another = new Thing(100);  
basket.contains(another); // true or false?

class Thing {  
    public int value;  

    public Thing (int x) {
        value = x;
    }

    equals (Thing x) {
        if (x.value == value) return true;
        return false;
    }
}

이것이 반환 class되도록 구현되어야 합니까?contains()true

답변:


339

배열 implements리스트 인터페이스를 나열합니다.

메소드 에서 Javadoc을List 보면 contains메소드를 사용하여 equals()두 오브젝트가 동일한 지 평가 하는 것을 볼 수 있습니다 .


61
equals ()를 재정의하려는 경우 hashcode () 메서드도 재정의해야합니다. 그렇지 않으면 컬렉션을 사용하는 동안 예상대로 작동하지 않을 수 있습니까?
Mohd Farid

34
정답이지만을 승인하기 위해 equals 메소드를 변경해야 Object합니다 Thing. 그렇지 않으면 equals 메소드가 사용되지 않습니다. :)
mdierker

1
이클립스가 소스 메뉴에서 "Generate hashCode () and equals"를 가지고 있음을 스스로 발견했습니다.
Volodymyr Krupach

이것은 제목의 질문에 대한 답이지만 설명의 질문에는 대답하지 않습니다. 즉, "정확히 동일한 생성자 입력으로 다른 객체를 만들면 contains () 메서드가 두 객체가 동일한 것으로 평가합니까?"
robguinness

3
Collections최적화 된 방식으로 작업을 수행합니다. 즉 , 두 객체 contains()hashCodes 를 먼저 확인한 다음 호출합니다 equals(). 경우 hashCode들 (두 개의 서로 다른 인스턴스의 경우 항상하는 다른 Thing)에 equals()메서드가 호출되지 않습니다. 대체로을 재정의 할 때 equals()재정의 hashCode()도 잊지 않아야합니다 .
Sevastyan Savanyuk

52

올바른 구현은

public class Thing
{
    public int value;  

    public Thing (int x)
    {
        this.value = x;
    }

    @Override
    public boolean equals(Object object)
    {
        boolean sameSame = false;

        if (object != null && object instanceof Thing)
        {
            sameSame = this.value == ((Thing) object).value;
        }

        return sameSame;
    }
}

1
if진술은 불필요합니다. instanceof충분하다.
Paul

@Paul 당신이 말하는 문장의 어느 부분?
ChristopheCVB

4
object != null때문에 조건이 불필요한 object instanceof Thing물체가없는 것에 대한 검사도줍니다.
Alexander Farber

15

ArrayList는 클래스 (귀하의 Thing 클래스)에서 구현 된 equals 메소드를 사용하여 equals 비교를 수행합니다.


12

일반적으로 성능 향상을 위해서라도 재정의 hashCode()할 때마다 재정의해야합니다 equals(). HashCode()비교할 때 객체가 정렬 될 '버킷'을 결정하므로 equal()true로 평가 되는 두 객체 는 모두 같은 값을 반환해야합니다 hashCode value(). 기본 동작을 기억할 수 없습니다 hashCode()(0을 반환하면 코드가 작동하지만 느리게 작동하지만 주소를 반환하면 코드가 실패합니다). 재정의를 잊어 버렸기 때문에 코드가 실패했을 때를 기억합니다 hashCode(). :)


7

객체에서 equals 메소드를 사용합니다. 따라서 Thing이 equals를 재정의하고 객체에 저장된 변수를 사용하여 비교하지 않으면 contains()메소드에서 true를 반환하지 않습니다 .


6
class Thing {  
    public int value;  

    public Thing (int x) {
        value = x;
    }

    equals (Thing x) {
        if (x.value == value) return true;
        return false;
    }
}

다음과 같이 작성해야합니다.

class Thing {  
    public int value;  

    public Thing (int x) {
        value = x;
    }

    public boolean equals (Object o) {
    Thing x = (Thing) o;
        if (x.value == value) return true;
        return false;
    }
}

이제는 작동합니다.)


6
Thing x = (Thing) o; 다른 객체가 null인지 먼저 확인하지 않고
steelshark

5

value기본 유형이 아닌 경우 다음 구현이 잘못되었습니다 .

public class Thing
{
    public Object value;  

    public Thing (Object x)
    {
        this.value = x;
    }

    @Override
    public boolean equals(Object object)
    {
        boolean sameSame = false;

        if (object != null && object instanceof Thing)
        {
            sameSame = this.value == ((Thing) object).value;
        }

        return sameSame;
    }
}

이 경우 다음을 제안합니다.

public class Thing {
    public Object value;  

    public Thing (Object x) {
        value = x;
    }

    @Override
    public boolean equals(Object object) {

        if (object != null && object instanceof Thing) {
            Thing thing = (Thing) object;
            if (value == null) {
                return (thing.value == null);
            }
            else {
                return value.equals(thing.value);
            }
        }

        return false;
    }
}

중복을 제거하면서 이것을 구현하는 방법은 무엇입니까?
Sujay

4

다른 포스터는 contains () 작동 방식에 대한 질문을 해결했습니다.

귀하의 질문에서 똑같이 중요한 측면은 equals ()를 올바르게 구현하는 방법입니다. 그리고 이것에 대한 대답은 실제로이 특정 클래스의 객체 평등을 구성하는 것에 달려 있습니다. 제공 한 예에서, x = 5를 갖는 두 개의 다른 객체가있는 경우 동일한가요? 실제로 당신이하려는 일에 달려 있습니다.

객체 평등에만 관심이 있다면 .equals () 의 기본 구현 (Object에서 제공 한 것)은 ID 만 사용합니다 (예 : this == other). 그것이 원하는 것이라면 클래스에서 equals ()를 구현하지 마십시오 (Object에서 상속하도록하십시오). 작성한 코드는 신원을 얻으려는 경우에는 정확하지만 실제 클래스 b / c에는 나타나지 않으므로 기본 Object.equals () 구현을 사용하는 것보다 이점이 없습니다.

이 작업을 시작한 경우 Joshua Bloch의 Effective Java 책을 강력히 권장합니다. 잘 읽었으며 이러한 종류의 내용을 다루며 (ID 기반 비교 이상을 수행하려고 할 때 equals ()를 올바르게 구현하는 방법)


내 목적을 위해 동일한 값의 객체가 ArrayList에 있는지 확인하려고했습니다. 나는 그것이 일종의 핵이라고 생각합니다. 책 추천에 감사드립니다
Mantas Vidutis

3

JavaDoc 에서 바로 가기 :

부울 포함 (오브젝트 o)

이리스트에 지정된 요소가 포함되어있는 경우에 true를 리턴합니다. 보다 공식적으로,이 목록에 (o == null? e == null : o.equals (e)) 와 같은 요소 e가 하나 이상 포함 된 경우에만 true를 반환합니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.