繁体   English   中英

使用自定义相等函数检查两个集合是否相同(忽略顺序)

[英]Check if two collections are the same (ignoring order) using a custom equality function

我有两个Foo系列。 我无法更改Foo的实现,并且Foo的equals函数实现不正确。 我也不能从Foo继承。 我做自定义相等函数:我已经使用guava的Predicate函数实现了。 为了给您一个想法,实现看起来有点像这样。

new Predicate<Pair<Foo, Foo>>() {
        @Override
        public boolean apply(@Nullable Pair<Foo, Foo> input) {
          Foo one = input.getFirst();
          Foo two = input.getSecond();
          return Objects.equals(one.getId(), two.getId());
        }
      };

现在我需要检查两个Foo集合是否包含忽略订单的相同项目

我正在寻找使用此自定义等于函数的最佳方法。

您可以将您的课程包装在Guava Equivalence并将其存储在Sets中。

Equivalence<Foo> eq = new Equivalence<Foo>{
// implement equals and hashcode
};
Set<Equivalence<Foo>> set1 = new HashSet<>();
set1.add(eq.wrap(someFoo));

这样,您可以执行双向containsAll()或执行

Sets.difference(set1, set2).isEmpty()

为什么不使用带有自定义Comparator的简单SortedSet而不是自定义Predicate

    Comparator<Foo> comparator = new Comparator<Foo>() {

        public int compare(Foo o1, Foo o2) {
            return //your custom comparison
        }
    };
    SortedSet<Foo> sortedSet1 = newTreeSet(comparator);
    sortedSet1.addAll(firstCollection);
    SortedSet<Foo> sortedSet2 = newTreeSet(comparator);
    sortedSet2.addAll(secondCollection);

    sortedSet1.equals(sortedSet); //this is what you want

如果不想在操作后对列表进行排序,请复制列表或将其与Set一起使用(但使用Set [1,1,1] == [1])。

public class ListTest {
    public static void main(String[] args) {
        List<Integer> list1 = Arrays.asList(1, 2, 3, 4, 5);
        List<Integer> list2 = Arrays.asList(1, 2, 3, 4, 5);
        List<Integer> list3 = Arrays.asList(1, 2, 3, 4, 4);

        System.out.println(compare(list1, list2, (a, b) -> a - b));
        System.out.println(compare(list1, list3, (a, b) -> a - b));
    }

    private static <E> boolean compare(List<E> list1, List<E> list2, Comparator<E> comparator) {
        if(list1.size() != list2.size()) {
            return false;
        }
        Collections.sort(list1, comparator);
        Collections.sort(list2, comparator);
        Iterator<E> iterator1 = list1.iterator();
        Iterator<E> iterator2 = list2.iterator();
        while (iterator1.hasNext()) {
            if(comparator.compare(iterator1.next(), iterator2.next()) != 0) {
                return false;
            }
        }
        return true;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM