문제

컬렉션 크기별로 정렬 된 컬렉션 (이 경우 일반적으로 반드시, 일반적으로 반드시 필요하지 않음)을 갖고 싶습니다. 이것은 비교기가 equals ()와 일치하도록 규모를 위반하는 것으로 보이며, 즉 두 컬렉션이 다른 요소를 갖는 데 불평등 할 수 있지만 동일한 값과 비교할 수 있습니다 (동일한 수의 요소가 있기 때문에).

개념적으로, 나는 또한 동일한 크기의 세트를 정렬하는 비교 방법을 넣을 수도 있지만, 종류의 사용은 그것을 이용하지 못할 것이며, 동일한 크기의 컬렉션을 비교하는 유용한 + 직관적 인 방법은 없습니다 (적어도. , 내 특별한 경우), 폐기물처럼 보입니다.

이 불일치의 경우 문제처럼 보입니까?

도움이 되었습니까?

해결책

CHSSPLY76이 의견에 썼 듯이, 해시 코드를 사용하여 두 컬렉션의 크기가 같지만 동일하지 않은 경우 비교 호출을 결정할 수 있습니다. 이것은 같은 크기의 두 개의 컬렉션이있는 드문 경우를 제외하고는 잘 작동하지만 동일하지는 않지만 동일한 해시 코드가 있습니다. 틀림없이, 그 일이 일어날 가능성은 꽤 작지만 생각할 수 있습니다. 해시 코드 대신에 정말로 조심하고 싶다면 System.IentityHashCode를 대신 사용하십시오. 이렇게하면 각 컬렉션에 대해 고유 한 번호가 제공되며 충돌을받지 않아야합니다.

하루가 끝나면 크기로 세트에 컬렉션을 세트에 정렬하는 기능을 제공하며 크기가 일치하는 두 개의 컬렉션의 경우 임의 순서가 있습니다. 이것이 필요한 전부라면 일반적인 비교보다 훨씬 느리지 않습니다. 다른 JVM 인스턴스간에 일관성을 유지하기 위해 주문이 필요하다면, 이것은 작동하지 않으며 다른 방법으로 수행해야합니다.

의사 코드 :

if (a.equals(b)) {
    return 0;
} else if (a.size() > b.size()) {
    return 1;
} else if (b.size() > a.size()) {
    return -1;
} else {
    return System.identityHashCode(a) > System.identityHashCode(b) ? 1 : -1;
}

다른 팁

SortedSet 인터페이스는 코어를 확장합니다 Set 따라서 요약 된 계약을 준수해야합니다 Set 사양.

이를 달성하는 유일한 방법은 요소를 갖는 것입니다. equal() 방법 동작은 귀하와 일치합니다 Comparator - 그 이유는 그 핵심입니다 Set 평등에 따라 작동합니다 SortedSet 비교에 따라 작동합니다.

예를 들어, add() 코어 세트 인터페이스에 정의 된 메소드 이미가있는 요소가있는 경우 세트에 요소를 추가 할 수 없음을 지정합니다. equal() 메소드는이 새로운 요소로 인수로 TRUE를 반환합니다. 잘, SortedSet 사용하지 않습니다 equal(), 그것은 사용합니다 compareTo(). 그래서 당신의 경우 compareTo() 보고 false 당신의 요소는하더라도 추가됩니다 equals() 돌아와야했다 true, 따라서 Set 계약.

이 중 어느 것도 아닙니다 현실적인 그러나 문제 그 자체로. SortedSet 행동은 항상 일관성이 있습니다 compare() vs equals() 그렇지 않습니다.

이것은 비교기가 equals ()와 일치하도록 규모를 위반하는 것으로 보이며, 즉 두 컬렉션이 다른 요소를 갖는 데 불평등 할 수 있지만 동일한 값과 비교할 수 있습니다 (동일한 수의 요소가 있기 때문에).

(Javadoc에서) 명시된 요구 사항은 없습니다. Comparator 객체의 구현과 일치하십시오 boolean equals(Object).

주목하십시오 Comparable 그리고 Comparator ~이다 독특한 인터페이스 다른 목적으로. Comparable 클래스의 '자연'순서를 정의하는 데 사용됩니다. 그런 맥락에서 그것은 나쁜 생각 일 것입니다. equals 그리고 compateTo 일관성이 없다. 대조적으로, a Comparator 클래스의 자연 순서에 다른 순서를 사용하려는 경우 사용됩니다.

편집 : SortedSet의 Javadoc의 전체 단락은 다음과 같습니다.

정렬 된 세트가 제공되는지 여부에 따라 정렬 된 세트가 제공되는 경우 정렬 된 세트가 세트 인터페이스를 올바르게 구현하려면 정렬 된 세트 (명시 적 비교기가 제공되는지 여부)와 일치해야합니다. (Equals와의 일관성에 대한 정확한 정의에 대해서는 비교 가능한 인터페이스 또는 비교기 인터페이스를 참조하십시오.) 세트 인터페이스가 평등 작동 측면에서 정의되기 때문에 정렬 된 세트는 비교 (또는 비교) 메소드를 사용하여 모든 요소 비교를 수행하기 때문입니다. ,이 방법에 의해 동일하다고 간주되는 두 가지 요소는 정렬 된 세트의 관점에서 동일합니다. 정렬 된 세트의 동작은 주문이 평등과 일치하지 않더라도 잘 정의됩니다. 설정 인터페이스의 일반 계약에 순종하지 않습니다.

나는 마지막 문장을 강조했다. 요점은 그러한 정렬 세트가 가장 기대할 수있는대로 작동하지만 일부 작업의 동작은 정확히 일치하지 않습니다. Set 사양 ... 사양이 동작을 equals 방법.

사실, 거기 ~이다 일관성에 대한 명시된 요구 사항 (내 실수)이지만 무시한 결과는 생각만큼 나쁘지 않습니다. 물론, 당신이 그렇게 해야하는지 결정하는 것은 달라집니다. 내 추정에 따르면, 코드에 철저히 주석하고 SortedSet이 '누출'되지 않도록하는 경우 괜찮아 야합니다.

그러나 "크기"컬렉션 만 보는 컬렉션의 비교기가 의미 론적 관점에서 작동한다는 것은 분명하지 않습니다. 내 말은, 2 개의 요소가있는 모든 컬렉션이 동일하다고 말하고 싶습니까? 이것은 당신의 세트가 주어진 크기의 하나의 컬렉션 만 포함 할 수 있음을 의미합니다 ...

이유가 없습니다 Comparator 동일한 결과를 반환해야합니다 equals(). 사실, Comparator API가 소개되었습니다 equals() 충분하지 않습니다 : 컬렉션을 정렬하려면 두 요소가 더 적거나 더 큰지 알아야합니다.

표준 API의 일부가 SET 인터페이스에 정의 된 계약을 중단하고 비교기를 사용하여 Equals 메소드 대신 평등을 정의하는 것은 SortedSet이 약간 이상합니다.

실제 문제가 컨테이션 된 컬렉션의 크기에 따라 컬렉션 모음을 정렬하는 경우 Collections.sort (List, Comparator>)를 사용하여 정렬 할 수있는 목록을 사용하는 것이 좋습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top