比较两个数组列表以保留它们之间的增量的有效方法

Efficient way of comparing two arraylists in order to retain a delta between them

这是我遇到的问题:

我需要比较两个 ArrayList 和 return 如果它们相同或不同,return 来自其中之一的新元素,可以说是枢轴。

这是数据集的行为:

我想要的:

示例:

A: [ 'a', 'b', 'c', 'd']   

B: [ 'a', 'c', 'd']

结果:列表不同,return元素'b'; A将是'work'List,我们将根据这个ArrayList中的新内容进行比较,因为B永远不会改变。

感谢您的回复和意见。

你的尽可能快的要求让我很困扰——我非常反对优化——我通常认为早期优化是最糟糕的编程实践之一。

如果你真的想这样做,只需按顺序遍历两个列表即可。

如果第一个条目匹配,则将那个条目放入 "Same" 堆中并递增两个索引。如果它们不同,将第一个 (lower/less-than) 个放入 "Different" 堆中并递增列出索引。以这种方式循环,直到你到达一个列表的末尾(另一个列表中的任何剩余显然都进入 "Different" 集合。

那应该给你 "close" 最快的方法。如果你想要绝对最快,那么你必须从使用数组开始,而不是列表,然后非常注意你在每一步中还做了什么——但算法应该仍然非常接近最优。

作为次优但更具可读性的示例,您可以使用一些集合操作。

Set set1=new HashSet(list1)
Set set2=new HashSet(list2)
Set same=set1.retainAll(set2) // I forget if retainAll modifies set1--if so you need to copy it first
set1.removeAll(list2)
set2.removeAll(list1)
Set different=set1.addAll(set2)

// at this point same contains all the similar values and different contains the ones that don't match.  Done.

本文简短易读,可能比您想象的更高效。如果这样的东西运行良好(比如,在速度不太重要的 GUI 代码中),那么自己编写代码将是一种不好的做法。

非常简单(假设列表按升序排列,可以很容易地更改为降序):

ArrayList<String> delta(ArrayList<String> a , ArrayList<String> b , Comparator<String> comp){
    if(a.isEmpty())
        return new ArrayList(b);
    if(b.isEmpty())
        return new ArrayList(a);

    Iterator<String> it_a = a.iterator();
    Iterator<String> it_b = b.iterator();

    ArrayList<String> delta = new ArrayList<>();

    String a_s = it_a.next() , b_s = it_b.next();
    boolean onechecked = false;

    while(!onechecked){
        int comp_v = comp.compare(a_s , b_s);

        if(comp_v == 0){
            //strings are equal -> ommit them
            if(it_a.hasNext())
                a_s = it_a.next();
            else
                onechecked = true;

            if(it_b.hasNext())
                b_s = it_b.next();
            else
                onechecked = true;
        }else if(comp_v < 0){
            //a_s is not part of b
            delta.add(a_s);
            if(it_a.hasNext())
                a_s = it_a.next();
            else
                onechecked = true;
        }else{
            //b_s is not part of a
            delta.add(b_s);
            if(it_b.hasNext())
                b_s = it_b.next();
            else
                onechecked = true;
        }
    }

    //add remaining items
    delta.add(it_a.hasNext() ? a_s : b_s);

    for(Iterator<String> it = (it_a.hasNext() ? it_a : it_b) ; it.hasNext();)
        delta.add(it.next());

    return delta;
}

抱歉没有添加任何解释,但代码必须说明一切,因为我不知道如何解释它。