Java ArrayList-순서가 중요하지 않은 두 목록이 동일한 지 어떻게 알 수 있습니까?


133

나는 두 가지 ArrayList유형의 Answer(자체 수업)을 가지고 있습니다.

두 목록을 비교하여 동일한 내용이 포함되어 있는지, 순서가 중요하지 않은지 확인하고 싶습니다.

예:

//These should be equal.
ArrayList<String> listA = {"a", "b", "c"}
ArrayList<String> listB = {"b", "c", "a"}

List.equals동일한 크기, 내용 및 요소 순서를 포함하는 경우 두 목록이 동일 함을 나타냅니다. 나는 똑같은 것을 원하지만 순서는 중요하지 않습니다.

이를 수행하는 간단한 방법이 있습니까? 아니면 중첩 된 for 루프를 수행하고 두 목록의 각 인덱스를 수동으로 확인해야합니까?

참고 : ArrayList다른 유형의 목록으로 변경할 수 없으므로 그대로 유지해야합니다.


4
이 질문에 대한 답변을 참조하십시오 : stackoverflow.com/a/1075699/1133011
David Kroukamp

자바의 List.containsAll (list) 참조
Sahil Jain

답변:


130

Collections.sort()를 사용 하여 두 목록을 정렬 한 다음 equals 메소드를 사용할 수 있습니다. 훨씬 더 나은 해결책은 주문하기 전에 길이가 같은지 먼저 확인하고 그렇지 않은 경우 같지 않은 경우 정렬 한 다음 같음을 사용하는 것입니다. 예를 들어 두 개의 문자열 목록이 있으면 다음과 같습니다.

public  boolean equalLists(List<String> one, List<String> two){     
    if (one == null && two == null){
        return true;
    }

    if((one == null && two != null) 
      || one != null && two == null
      || one.size() != two.size()){
        return false;
    }

    //to avoid messing the order of the lists we will use a copy
    //as noted in comments by A. R. S.
    one = new ArrayList<String>(one); 
    two = new ArrayList<String>(two);   

    Collections.sort(one);
    Collections.sort(two);      
    return one.equals(two);
}

20
원본 목록의 순서를 훼손하지 마십시오 Collections.sort. 즉, 사본을 전달하십시오.
arshajii

@ARS 예, 확실한 부작용이지만 특정 상황에서 중요한 경우에만 가능합니다.
Jacob Schoen

3
당신은 one = new ArrayList<String>(one); two = new ArrayList<String>(two);논쟁을 망치지 않기 위해 추가 할 수 있습니다 .
arshajii

@jschoen Collections.sort ()를 수행하려고하면이 오류가 발생합니다. 바운드 불일치 : Collections 유형의 일반 메소드 sort (List <T>)는 인수 (ArrayList <Answer>)에 적용 할 수 없습니다. 유추 된 유형 Answer는 바운드 매개 변수 <T extends Comparable <? super T >>
iaacp 2018

3
함수 내부의 두 번째 "if"문 if(one == null || two == null || one.size() != two.size()){ return false; }은 이미 하나와 둘 다 null인지 확인하기 때문에 단순화 될 수 있습니다.
Hugo

151

아마 가장 쉬운 방법은 모든 목록은 다음과 같습니다

listA.containsAll(listB) && listB.containsAll(listA)

5
그 재미는 어디에 있습니까? 진지하게 이것은 이것이 더 나은 해결책 일 것입니다.
Jacob Schoen

67
여부에 따라 다름 [a, b, c][c, b, a, b]같은 내용을 가지고 간주됩니다. 이 답변은 그들이 할 것이라고 말하지만 OP에 대해서는 그렇지 않습니다 (하나는 사본을 포함하고 다른 하나는 그렇지 않기 때문에). 효율성 문제에 대해 아무 말도하지 않습니다.
yshavit

4
주석을 기반으로 향상-System.out.println ((((l1.size () == l2.size ()) && l2.containsAll (l1) && l1.containsAll (l2)));
Nrj

8
@Nrj, [1,2,2]와 [2,1,1]은 어떻습니까?
ROMANIA_engineer

3
이 방법은 O (n ^ 2)의 복잡성을 가지고 있습니다. 예를 들어 [1,2,3] 및 [3,2,1]의 역순 인 두 목록을 고려하십시오. 첫 번째 요소의 경우 n 개의 요소를 스캔하고 두 번째 n-1 요소 등을 스캔해야합니다. 따라서 복잡도는 n ^ 2입니다. 더 나은 방법은 정렬하고 같음을 사용하는 것입니다. 그것은 O (N * 로그 (N))의 복잡성을해야합니다
puneet

90

구조를 다시 한 번 Apache Commons Collections :

List<String> listA = Arrays.asList("a", "b", "b", "c");
List<String> listB = Arrays.asList("b", "c", "a", "b");
System.out.println(CollectionUtils.isEqualCollection(listA, listB)); // true

 

List<String> listC = Arrays.asList("a", "b", "c");
List<String> listD = Arrays.asList("a", "b", "c", "c");
System.out.println(CollectionUtils.isEqualCollection(listC, listD)); // false

문서 :

org.apache.commons.collections4.CollectionUtils

public static boolean isEqualCollection(java.util.Collection a,
                                        java.util.Collection b)

true주어진 Collections에 정확히 동일한 카디널리티가있는 동일한 요소가 포함되어 있으면를 반환 합니다.

즉, 카디널리티 IFF에 전자 에 카디널리티 같다 에서 , B 각각의 요소에 대해, E 에 또는 B .

매개 변수 :

  • a -첫 번째 컬렉션은 null
  • b -두 번째 컬렉션은 null

반환 값 : true컬렉션이 동일한 카디널리티와 같은 요소를 포함 IFF에.


구현은 DiddiZ의 답변과 다소 비슷해 보입니다.
user227353

그래 ...하지만 대답이 false그렇다면 범인 (두 목록에 공통적이지 않은 요소)을 잡는 것은 어떻습니까? 내 대답을 참조하십시오.
마이크 설치류

implementation 'org.apache.commons:commons-collections4:4.3'오류 Caused by: com.android.builder.dexing.DexArchiveBuilderException: Failed to process 경로 가 남았습니다 .
Aliton Oliveira

13
// helper class, so we don't have to do a whole lot of autoboxing
private static class Count {
    public int count = 0;
}

public boolean haveSameElements(final List<String> list1, final List<String> list2) {
    // (list1, list1) is always true
    if (list1 == list2) return true;

    // If either list is null, or the lengths are not equal, they can't possibly match 
    if (list1 == null || list2 == null || list1.size() != list2.size())
        return false;

    // (switch the two checks above if (null, null) should return false)

    Map<String, Count> counts = new HashMap<>();

    // Count the items in list1
    for (String item : list1) {
        if (!counts.containsKey(item)) counts.put(item, new Count());
        counts.get(item).count += 1;
    }

    // Subtract the count of items in list2
    for (String item : list2) {
        // If the map doesn't contain the item here, then this item wasn't in list1
        if (!counts.containsKey(item)) return false;
        counts.get(item).count -= 1;
    }

    // If any count is nonzero at this point, then the two lists don't match
    for (Map.Entry<String, Count> entry : counts.entrySet()) {
        if (entry.getValue().count != 0) return false;
    }

    return true;
}

와우, 다른 모든 솔루션보다 더 빠른 성능을 제공한다는 사실에 놀랐습니다. 그리고 그것은 초기를 지원합니다.
DiddiZ

이것은 또한 두번째 루프에서 단락 될 수 있으며, count음이되면 루프 바디를 단순화합니다. if(!counts.containsKey(item) || --counts.get(item).count < 0) return false;또한, 세번째 루프는 다음과 같이 단순화 될 수 있습니다for(Count c: counts.values()) if(c.count != 0) return false;
Holger

@Holger 첫 번째와 비슷한 것을 고려했을 것입니다 (0에 도달했을 때 카운트를 제거하면 같은 효과가 있지만 끝의 수표를 " counts비어 있는지 여부 "로 바꿉니다). 요점 : 맵을 사용하면 기본적으로 이것을 O (N + M) 문제로 바꾸고, 얻을 수있는 가장 큰 부스트입니다.
cHao

@cHao 그렇습니다. 이전 솔루션보다 시간이 더 복잡한 솔루션을 지적한 것은 당연합니다. iterables에 관한 최근 비슷한 질문이 있기 때문에 방금 생각했습니다. 우리는 이제 Java 8도 가지고 있기 때문에 다시 생각할 가치가 있습니다. 숫자가 음수가 될 때 두 번째 루프에서 단락하면 세 번째 루프가 더 이상 사용되지 않습니다. 또한 boxing을 피하는 것은 양날의 Map.merge검일 수 있으며 new 에서는 boxed integers를 사용하는 것이 대부분의 사용 사례에서 더 간단하고 효율적일 수 있습니다. 이 답변 도 참조하십시오 .
Holger

10

이 답변에 속임수가 없다고 말하고 싶습니다.

Bloch는 필수적이고 훌륭하고 간결한 Effective Java 에서 항목 47에서 "라이브러리를 알고 사용하십시오"라는 제목으로 "바퀴를 재발 명하지 마십시오"라고 말합니다. 그리고 그는 몇 가지 매우 분명한 이유를 제시합니다.

여기 CollectionUtils에 Apache Commons Collections 라이브러리의 메소드를 제안하는 몇 가지 답변이 있지만 이 질문에 대답하는 가장 아름답고 우아한 방법은 없습니다 .

Collection<Object> culprits = CollectionUtils.disjunction( list1, list2 );
if( ! culprits.isEmpty() ){
  // ... do something with the culprits, i.e. elements which are not common

}

Culprits : 즉 둘 다 공통적이지 않은 요소 Lists. 에 속하는 범인 결정 list1하고있는 list2비교적 간단 사용 CollectionUtils.intersection( list1, culprits )하고 CollectionUtils.intersection( list2, culprits ).
그러나 { "a", "a", "b"} disjunction와 { "a", "b", "b"}와 같은 경우에는 소프트웨어가 실패하지 않는 것을 제외하고는 차이가 있습니다. 원하는 작업의 미묘함 / 모호함의 본질.

Apache 엔지니어가 생성 한 것과 같은 작업에 대해서는 항상 소스 코드 (l. 287)를 검사 할 수 있습니다 . 코드를 사용하면 얻을 수있는 이점 중 하나는 코드를 철저히 시도하고 테스트했을뿐 아니라 여러 가지 중요한 사례와 문제가 예상되고 처리된다는 것입니다. 필요한 경우이 코드를 복사하여 마음의 내용에 맞게 조정할 수 있습니다.


NB 저는 처음에는 CollectionUtils자신에게 직접 적용 할 수있는 오버로드 된 버전을 제공하는 방법 이 없다는 것에 실망했습니다 Comparator(따라서 equals목적에 맞게 재정의 할 수 있음 ).

그러나 collections4 4.0에는 Equator"T 유형의 객체 간 동등성을 결정하는" 새로운 클래스가 있습니다. collections4 CollectionUtils.java의 소스 코드를 살펴보면 몇 가지 메소드와 함께 이것을 사용하는 것 같지만 CardinalityHelper클래스를 사용하여 파일 상단의 메소드에는 적용 할 수 없습니다 ... 포함 disjunction하고 intersection.

나는 그것이 아닌 사소한 때문에 아파치 사람들이 아직이 주위에 도착하지 않은 것으로 추측 : 당신이 대신 요소의 고유 사용하는 "AbstractEquatingCollection"클래스, 같은 것을 만들어야 할 것입니다 equalshashCode방법을 대신들을 사용하는 것을 의 Equator와 같은 모든 기본적인 방법에 대한 add, contains등 NB는 소스 코드를 볼 때 실제로 AbstractCollection구현하지 않습니다 add,도 등의 추상적 인 서브 클래스를 할 AbstractSet... 당신과 같은 구체적인 클래스까지 기다려야 HashSetArrayList이전 add구현됩니다. 꽤 두통.

그동안이 공간을 지켜봐야한다고 생각합니다. 분명한 임시 해결책은 모든 요소를 ​​맞춤형 래퍼 클래스로 래핑하여 원하는 평등 을 사용 equals하고 hashCode구현 한 Collections다음 래퍼 객체 를 조작하는 것 입니다.


또한 현명한 사람은 "의존 비용을 알고"
Stanislaw Baranski

@StanislawBaranski 흥미로운 의견입니다. 그러한 라이브러리에 너무 의존해서는 안된다는 제안입니까? 이미 큰 믿음의 도약 인 컴퓨터에서 OS를 사용할 때 그렇지 않습니까? 내가 아파치 라이브러리를 사용하게 된 이유는 그것들을 실제로 매우 높은 품질로 받아들이고 그들의 방법이 그들의 "계약"을 준수하고 철저히 테스트되었다고 가정하기 때문이다. 더 신뢰할 수있는 코드를 개발하는 데 시간이 얼마나 걸립니까? 공개 소스 Apache 라이브러리에서 코드를 복사하고 면밀히
mike rodent

8

항목의 카디널리티가 중요하지 않은 경우 (즉, 반복되는 요소가 하나로 간주 됨) 정렬하지 않고이를 수행 할 수있는 방법이 있습니다.

boolean result = new HashSet<>(listA).equals(new HashSet<>(listB));

이것은 생성됩니다 Set각각의 아웃 List한 다음 사용 HashSetequals방법을 무시합니다 (물론) 순서를.

카디널리티가 중요한 경우, 귀하는 다음과 같은 시설을 제공해야합니다 List. 이 경우 @jschoen의 대답이 더 적합합니다.


listA = [a, b, c, c] 및 listB = [a, b, c] 인 경우 어떻게됩니까? 결과는 사실이지만 목록이 같지 않습니다.
Nikolas

6

목록을 Guava의 Multiset으로 변환하면 매우 효과적입니다. 순서에 관계없이 비교되며 중복 요소도 고려됩니다.

static <T> boolean equalsIgnoreOrder(List<T> a, List<T> b) {
    return ImmutableMultiset.copyOf(a).equals(ImmutableMultiset.copyOf(b));
}

assert equalsIgnoreOrder(ImmutableList.of(3, 1, 2), ImmutableList.of(2, 1, 3));
assert !equalsIgnoreOrder(ImmutableList.of(1), ImmutableList.of(1, 1));

6

이것은 @cHao 솔루션을 기반으로합니다. 몇 가지 수정 사항과 성능 개선 사항이 포함되었습니다. 이 방법은 동일 순서의 복사 솔루션보다 약 두 배 빠릅니다. 모든 컬렉션 유형에 적용됩니다. 빈 컬렉션과 null은 동일한 것으로 간주됩니다. 당신의 이점에 사용;)

/**
 * Returns if both {@link Collection Collections} contains the same elements, in the same quantities, regardless of order and collection type.
 * <p>
 * Empty collections and {@code null} are regarded as equal.
 */
public static <T> boolean haveSameElements(Collection<T> col1, Collection<T> col2) {
    if (col1 == col2)
        return true;

    // If either list is null, return whether the other is empty
    if (col1 == null)
        return col2.isEmpty();
    if (col2 == null)
        return col1.isEmpty();

    // If lengths are not equal, they can't possibly match
    if (col1.size() != col2.size())
        return false;

    // Helper class, so we don't have to do a whole lot of autoboxing
    class Count
    {
        // Initialize as 1, as we would increment it anyway
        public int count = 1;
    }

    final Map<T, Count> counts = new HashMap<>();

    // Count the items in col1
    for (final T item : col1) {
        final Count count = counts.get(item);
        if (count != null)
            count.count++;
        else
            // If the map doesn't contain the item, put a new count
            counts.put(item, new Count());
    }

    // Subtract the count of items in col2
    for (final T item : col2) {
        final Count count = counts.get(item);
        // If the map doesn't contain the item, or the count is already reduced to 0, the lists are unequal 
        if (count == null || count.count == 0)
            return false;
        count.count--;
    }

    // At this point, both collections are equal.
    // Both have the same length, and for any counter to be unequal to zero, there would have to be an element in col2 which is not in col1, but this is checked in the second loop, as @holger pointed out.
    return true;
}

합계 카운터를 사용하여 최종 for-loop를 건너 뛸 수 있습니다. 합계 카운터는 각 단계의 총 수를 계산합니다. 첫 번째 for- 루프에서 합계 카운터를 늘리고 두 번째 for- 루프에서는 합계 카운터를 줄입니다. 합계 카운터가 0보다 크면 목록이 일치하지 않습니다. 그렇지 않으면 일치합니다. 현재 마지막 for-loop에서는 모든 카운트가 0인지, 즉 모든 카운트의 합이 0인지 확인합니다. 합계 카운터 종류를 사용하면이 검사가 반대로되어 총 개수가 0이면 true를, 그렇지 않으면 false를 반환합니다.
SatA

IMO는 목록이 일치 할 때 (가장 최악의 시나리오) for-loop가 불필요한 다른 O (n)을 추가하기 때문에 for-loop를 건너 뛸 가치가 있습니다.
SatA

@SatA는 실제로 교체하지 않고 세 번째 루프를 제거 할 수 있습니다. false키가 존재하지 않거나 개수가 음수가되면 두 번째 루프는 이미 반환 됩니다. 두 목록의 전체 크기가 일치하기 때문에 (앞에서 확인 했음) 다른 키에 대해 음수 값이없는 키에 대해서는 양수 값을 가질 수 없으므로 두 번째 루프 후에 0이 아닌 값을 가질 수 없습니다.
Holger 2016 년

@holger 그것은 당신이 절대적으로 올바른 것 같습니다. 내가 알 수있는 한, 세 번째 루프는 전혀 필요하지 않습니다.
SatA

@SatA… Java 8을 사용하면 이 답변 과 같이 간결하게 구현할 수 있습니다 .
Holger 2016 년

5

컴퓨터 나 프로그래밍 언어가 없으면 어떻게해야하는지 생각해보십시오. 두 가지 요소 목록을 제공하며 동일한 요소가 포함되어 있는지 알려줘야합니다. 어떻게 하시겠습니까?

위에서 언급했듯이 한 가지 방법은 목록을 정렬 한 다음 요소별로 이동하여 동일한 지 확인하는 것입니다 (이것이 무엇인지 List.equals). 즉, 목록을 수정할 수 있거나 복사 할 수 있으며 할당에 대해 알지 못하면 둘 중 하나 또는 둘 다 허용되는지 알 수 없습니다.

또 다른 방법은 각 요소가 몇 번이나 나타나는지를 세면서 각 목록을 살펴 보는 것입니다. 마지막에 두 목록의 개수가 모두 같으면 요소가 같습니다. 이를위한 코드는 각 목록을 맵으로 변환 elem -> (# of times the elem appears in the list)한 다음 equals두 맵 을 호출 하는 것입니다. 맵이 HashMap인 경우 비교와 마찬가지로 각 변환은 O (N) 연산입니다. 그것은 여분의 메모리를 희생시키면서 시간면에서 꽤 효율적인 알고리즘을 제공 할 것입니다.


5

나는이 같은 문제가 있었고 다른 해결책을 생각해 냈습니다. 이것은 복제본이 관련된 경우에도 작동합니다.

public static boolean equalsWithoutOrder(List<?> fst, List<?> snd){
  if(fst != null && snd != null){
    if(fst.size() == snd.size()){
      // create copied lists so the original list is not modified
      List<?> cfst = new ArrayList<Object>(fst);
      List<?> csnd = new ArrayList<Object>(snd);

      Iterator<?> ifst = cfst.iterator();
      boolean foundEqualObject;
      while( ifst.hasNext() ){
        Iterator<?> isnd = csnd.iterator();
        foundEqualObject = false;
        while( isnd.hasNext() ){
          if( ifst.next().equals(isnd.next()) ){
            ifst.remove();
            isnd.remove();
            foundEqualObject = true;
            break;
          }
        }

        if( !foundEqualObject ){
          // fail early
          break;
        }
      }
      if(cfst.isEmpty()){ //both temporary lists have the same size
        return true;
      }
    }
  }else if( fst == null && snd == null ){
    return true;
  }
  return false;
}

다른 솔루션과 비교하여 장점 :

  • O (N²)보다 작은 복잡성 (여기서는 다른 답변의 솔루션과 비교하여 실제 성능을 테스트하지는 않았지만);
  • 일찍 나옵니다.
  • null을 검사합니다.
  • 중복이 포함 된 경우에도 작동합니다. 배열 [1,2,3,3]과 다른 배열 이있는 경우 [1,2,2,3]여기에서 대부분의 솔루션은 순서를 고려하지 않을 때 동일하다는 것을 알려줍니다. 이 솔루션은 임시 목록에서 동일한 요소를 제거하여이를 방지합니다.
  • 의미 평등 ( equals)을 사용하고 참조 평등 ( ==)을 사용 하지 않습니다 .
  • itens를 정렬하지 않으므로이 implement Comparable솔루션을 작동시키기 위해 정렬 할 필요가 없습니다 .

3

모음을 정렬하지 않고 [ "A" "B" "C"]가 [ "B" "B" "A" "C"]와 같지 않은 결과가 필요한 경우,

l1.containsAll(l2)&&l2.containsAll(l1)

충분하지 않은 경우 크기를 확인해야합니다.

    List<String> l1 =Arrays.asList("A","A","B","C");
    List<String> l2 =Arrays.asList("A","B","C");
    List<String> l3 =Arrays.asList("A","B","C");

    System.out.println(l1.containsAll(l2)&&l2.containsAll(l1));//cautions, this will be true
    System.out.println(isListEqualsWithoutOrder(l1,l2));//false as expected

    System.out.println(l3.containsAll(l2)&&l2.containsAll(l3));//true as expected
    System.out.println(isListEqualsWithoutOrder(l2,l3));//true as expected


    public static boolean isListEqualsWithoutOrder(List<String> l1, List<String> l2) {
        return l1.size()==l2.size() && l1.containsAll(l2)&&l2.containsAll(l1);
}

2

CollectionUtils 빼기 방법을 활용하는 솔루션 :

import static org.apache.commons.collections15.CollectionUtils.subtract;

public class CollectionUtils {
  static public <T> boolean equals(Collection<? extends T> a, Collection<? extends T> b) {
    if (a == null && b == null)
      return true;
    if (a == null || b == null || a.size() != b.size())
      return false;
    return subtract(a, b).size() == 0 && subtract(a, b).size() == 0;
  }
}

1

순서에 관심이 있다면 equals 메소드를 사용하십시오.

list1.equals(list2)

순서를 신경 쓰지 않으면 이것을 사용하십시오.

Collections.sort(list1);
Collections.sort(list2);      
list1.equals(list2)

4
그는 질서에 관심 이 없다고 말합니다 .
마이크 설치류

0

두 가지 장점 중 최고 [@DiddiZ, @Chalkos] : 주로 @Chalkos 메서드를 기반으로하지만 버그 (ifst.next ())를 수정하고 초기 검사 (@DiddiZ에서 가져옴)를 개선 할뿐만 아니라 첫 번째 컬렉션을 복사합니다 (두 번째 컬렉션의 복사본에서 항목을 제거하기 만 함).

해싱 기능이나 정렬이 필요하지 않고 불평등에 조기에 존재하게하는 것이 가장 효율적인 구현입니다. 수천 개 이상의 컬렉션 길이가 있고 매우 간단한 해싱 함수가 아닌 한입니다.

public static <T> boolean isCollectionMatch(Collection<T> one, Collection<T> two) {
    if (one == two)
        return true;

    // If either list is null, return whether the other is empty
    if (one == null)
        return two.isEmpty();
    if (two == null)
        return one.isEmpty();

    // If lengths are not equal, they can't possibly match
    if (one.size() != two.size())
        return false;

    // copy the second list, so it can be modified
    final List<T> ctwo = new ArrayList<>(two);

    for (T itm : one) {
        Iterator<T> it = ctwo.iterator();
        boolean gotEq = false;
        while (it.hasNext()) {
            if (itm.equals(it.next())) {
                it.remove();
                gotEq = true;
                break;
            }
        }
        if (!gotEq) return false;
    }
    // All elements in one were found in two, and they're the same size.
    return true;
}

내가 실수하지 않으면 가치있는 시나리오 에서이 알고리즘의 복잡성 (목록이 동일하지만 반대 방식으로 정렬 된 경우)은 O (N * N!)입니다.
SatA

실제로 각 반복마다 배열 크기가 감소하므로 O (N * (N / 2))입니다.
재즈 길

0

null 값을 포함 할 수있는 배열 목록이 같은지 확인하는 다른 방법입니다.

List listA = Arrays.asList(null, "b", "c");
List listB = Arrays.asList("b", "c", null);

System.out.println(checkEquality(listA, listB)); // will return TRUE


private List<String> getSortedArrayList(List<String> arrayList)
{
    String[] array = arrayList.toArray(new String[arrayList.size()]);

    Arrays.sort(array, new Comparator<String>()
    {
        @Override
        public int compare(String o1, String o2)
        {
            if (o1 == null && o2 == null)
            {
                return 0;
            }
            if (o1 == null)
            {
                return 1;
            }
            if (o2 == null)
            {
                return -1;
            }
            return o1.compareTo(o2);
        }
    });

    return new ArrayList(Arrays.asList(array));
}

private Boolean checkEquality(List<String> listA, List<String> listB)
{
    listA = getSortedArrayList(listA);
    listB = getSortedArrayList(listB);

    String[] arrayA = listA.toArray(new String[listA.size()]);
    String[] arrayB = listB.toArray(new String[listB.size()]);

    return Arrays.deepEquals(arrayA, arrayB);
}

목록과 배열 사이의 모든 복사의 요점은 무엇입니까?
Holger 2016 년

0

이것에 대한 나의 해결책. 너무 시원하지는 않지만 잘 작동합니다.

public static boolean isEqualCollection(List<?> a, List<?> b) {

    if (a == null || b == null) {
        throw new NullPointerException("The list a and b must be not null.");
    }

    if (a.size() != b.size()) {
        return false;
    }

    List<?> bCopy = new ArrayList<Object>(b);

    for (int i = 0; i < a.size(); i++) {

        for (int j = 0; j < bCopy.size(); j++) {
            if (a.get(i).equals(bCopy.get(j))) {
                bCopy.remove(j);
                break;
            }
        }
    }

    return bCopy.isEmpty();
}

-1

이 경우 목록 { "a", "b"} 및 { "b", "a"}는 동일합니다. { "a", "b"}와 { "b", "a", "c"}이 (가) 동일하지 않습니다. 복합 객체 목록을 사용하는 경우 containsAll 이 내부에서 사용하므로 equals 메서드 를 재정의 해야합니다.

if (oneList.size() == secondList.size() && oneList.containsAll(secondList)){
        areEqual = true;
}

-1 : { "a", "a", "b"} 및 { "a", "b", "b"}로 잘못된 답변을 제공합니다 AbstractCollection.containsAll(). 소스 코드를 확인하십시오 . 에 대해 이야기 Lists하지 말고 중복 요소를 허용해야합니다 Sets. 내 대답을 참조하십시오.
마이크 설치류
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.