如何比较两个数组列表与自定义比较器的相等性?

时间:2015-05-07 16:07:49

标签: java generics collections comparison

具体来说,我有两个清单:

List<SystemUserWithNameAndId> list1;
List<SystemUserWithNameAndId> list2;

我想检查它们是否包含相同的系统用户,并且订购不是问题。我尝试先使用比较器对它们进行排序,然后使用列表的equals()方法检查它们是否相等。但我不想覆盖SystemUserWithNameAndId的equals方法,我想知道我是否可以使用我为排序创建的比较器或类似的比较器来检查相等性,而不会在排序后显式迭代列表。

Comparator<SystemUserWithNameAndId> systemUserComparator = new Comparator<SystemUserWithNameAndId>()
    {

        @Override
        public int compare(SystemUserWithNameAndId systemUser1, SystemUserWithNameAndId systemUser2)
        {
            final int systemUserId1 = systemUser1.getSystemUserId();
            final int systemUserId2 = systemUser2.getSystemUserId();

            return systemUserId1 == systemUserId2 
                    ? 0
                    : systemUserId1 - systemUserId2;
        }
    };

    Collections.sort(systemUsers1, systemUserComparator);
    Collections.sort(systemUsers2, systemUserComparator);

    return systemUsers1.equals(systemUsers2);

理想情况下,我希望能够说,

CollectionUtils.isEqualCollections(systemUsers1, systemUsers2, someCustomComparator);

2 个答案:

答案 0 :(得分:5)

只需实现迭代的方法,并在每次需要时重用它:

$(function() {
  $('.tab-pane > ul').sortable().disableSelection();

  var 
    $tabs     = $('#tabs'),
    $tabItems = $('#myTab > li', $tabs);

  $('#myTab a:last').tab('show');
  $tabItems.droppable({
    accept: ".connectedSortable li",
    hoverClass: "ui-state-hover",
    drop: function(event, ui) {
      var 
        $item = $(this),
        href  = $item.children('a').attr('href'),
        $list = $(href).find('.connectedSortable');
      console.log($list);
      $list.append($('<li />').html(ui.draggable.html()).attr('class', ui.draggable.attr('class')));
      $list.closest('.tab-pane').addClass('active').siblings().removeClass('active');
      $item.addClass('active').siblings().removeClass('active');
    }// drop(event, ui)
  });// $tabItems.droppable()
  $('#external-tab > ul > li').draggable({
    appendTo: 'body',
    helper: 'clone'
  });
});// end of doc ready

答案 1 :(得分:2)

这是Java 8解决问题的方法。首先确保列表长度相等:

List<SystemUserWithNameAndId> list1 = ... ;
List<SystemUserWithNameAndId> list2 = ... ;

if (list1.size() != list2.size()) {
    return false;
}

现在使用新的比较器实用程序构建Comparator。我们的想法是,大多数比较器不是为比较器编写自定义逻辑,而是通过从两个对象中提取密钥来比较两个对象,然后比较密钥。这就是它的作用。

Comparator<SystemUserWithNameAndId> comp =
    Comparator.comparingInt(SystemUserWithNameAndId::getSystemUserId);

对列表进行排序。当然,如果您不希望您的功能具有排序其输入的副作用,您可能希望在排序之前制作副本。如果您的输入列表不是随机访问(现在谁使用LinkedList?),您可能还希望将它们复制到ArrayList以便于随机访问。

list1.sort(comp);
list2.sort(comp);

在列表的索引上运行流,在每对上调用比较器。如果元素根据此比较器等于,则比较器返回0。如果对于所有元素对都是如此,则列表是相等的。

return IntStream.range(0, list1.size())
    .allMatch(i -> comp.compare(list1.get(i), list2.get(i)) == 0);