1 /* 2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"). 5 * You may not use this file except in compliance with the License. 6 * A copy of the License is located at 7 * 8 * http://aws.amazon.com/apache2.0 9 * 10 * or in the "license" file accompanying this file. This file is distributed 11 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 * express or implied. See the License for the specific language governing 13 * permissions and limitations under the License. 14 */ 15 16 package software.amazon.awssdk.testutils; 17 18 import java.util.Collection; 19 import java.util.HashSet; 20 import java.util.Set; 21 22 /** 23 * This class includes some utility methods for comparing two unordered 24 * collections. 25 */ 26 public final class UnorderedCollectionComparator { 27 UnorderedCollectionComparator()28 private UnorderedCollectionComparator() { 29 } 30 31 /** 32 * Compares two unordered lists of the same type. 33 */ equalUnorderedCollections( Collection<T> colA, Collection<T> colB)34 public static <T> boolean equalUnorderedCollections( 35 Collection<T> colA, Collection<T> colB) { 36 return equalUnorderedCollections(colA, colB, (a, b) -> (a == b) || a != null && a.equals(b)); 37 } 38 39 /** 40 * Compares two unordered lists of different types, using the specified 41 * cross-type comparator. Null collections are treated as empty ones. 42 * Naively implemented using N(n^2) algorithm. 43 */ equalUnorderedCollections( Collection<A> colA, Collection<B> colB, final CrossTypeComparator<A, B> comparator)44 public static <A, B> boolean equalUnorderedCollections( 45 Collection<A> colA, Collection<B> colB, 46 final CrossTypeComparator<A, B> comparator) { 47 if (colA == null || colB == null) { 48 if ((colA == null || colA.isEmpty()) 49 && (colB == null || colB.isEmpty())) { 50 return true; 51 } else { 52 return false; 53 } 54 } 55 56 // Add all elements into sets to remove duplicates. 57 Set<A> setA = new HashSet<>(colA); 58 Set<B> setB = new HashSet<>(colB); 59 60 if (setA.size() != setB.size()) { 61 return false; 62 } 63 64 for (A a : setA) { 65 boolean foundA = false; 66 for (B b : setB) { 67 if (comparator.equals(a, b)) { 68 foundA = true; 69 break; 70 } 71 } 72 if (!foundA) { 73 return false; 74 } 75 } 76 return true; 77 } 78 79 /** 80 * A simple interface that attempts to compare objects of two different types 81 */ 82 public interface CrossTypeComparator<A, B> { 83 /** 84 * @return True if a and b should be treated as equal. 85 */ equals(A a, B b)86 boolean equals(A a, B b); 87 } 88 } 89