【问题标题】:Find the difference between two Arrays找出两个数组之间的差异
【发布时间】:2016-07-21 23:02:26
【问题描述】:

这看起来不像是现有交叉/联合问题的重复(我可能错了)。

我有两个 ArrayList,其中包含一个包含值的类,例如,

class A {
    private int value;

    public int getValue() {
        return value;
    }
}

我的清单是

ArrayList<A> first, second;

我想从first 和second 中找到两个索引,其中第一个索引指向first 中的项目,相应的值仅在first 中而不在second 中,其他索引是second 中的索引表示相应的值仅在 second 中,但不在 first 中。

例如(从中心行读取,数据在哪里):

hit                  *   *
index of first   0   1   2   3
----------------------------------
first.value      1   3   5   7
second.value     1 2   4   6 7 8
----------------------------------
index of second  0 1   2   3 4 5
hit                *   *   *   *

我想要1 2 和1 2 3 5 的两个索引。

注意:

  1. 我不喜欢使用 3rd 方库
  2. 值是整数和排序的,我的返回也必须按顺序。
  3. first 和 second 的长度不确定 - 任何一个都可能比另一个长。

谢谢。

PS:任何人都需要更多细节,这是我的问题的简化版本。 first其实是SQL查询的ResultSet,都是服务器上的记录,second是本地记录的列表(或者考虑从另一个本地数据库处理),我要做的就是删除服务器上的所有记录不包含在本地数据库(second)中的服务器(在first中),并将那些丢失的记录添加到远程数据库中。谢谢。


致@Tibrogargan

我的目标是将本地数据库 (sqlite) 增量传输到远程数据库 (MySQL)。本地数据库有一个名为LocalId 的字段(没有重复,不是主键)当然还有其他内容(~10 个字段),除了将必填字段(~5 个字段)复制到远程数据库之外,我还包括了一个字段来确定记录是否从本地数据库中删除。

作为其他要求,我已经将所有本地数据读入ArrayList,在本地数据库上按LocalId排序,并且可以通过rs访问所有远程数据,在远程数据库上按LocalId排序。

我早期版本的代码是在本地数据库中查找最后一个LocalId,并标记远程数据库上的所有记录,其中它们的LocalId 大于本地数据库上的最大LocalId。但是,直到我发现我并不总是删除本地数据库上的尾部记录时才正确,所以我发现有必要迭代所有消息并比较存在。

我不知道是否有任何“更好”的解决方案,但似乎如果我将所有本地消息加载到远程,性能会很糟糕?

哦,需要提一下,只有几十条消息需要删除并添加到远程,远程和本地数据集上都存在数百到 100+k 条记录。确定远程记录是否应标记为已删除的逻辑取决于本地数据集上是否存在相应的消息(相同的LocalId)。

【问题讨论】:

  • 显示你当前的实现。
  • 除了需要索引之外,这些只是经典的集合操作。看到这个:stackoverflow.com/questions/163998/…。 (获取索引很简单)
  • @Tide Gu 的值是唯一的吗?
  • 那么解决方案似乎微不足道。 sub = first.removeAll(second); for (elem : sub) { indicies.add(first.indexOf(elem)); } return indicies
  • 感谢@PaulBoddington,这是一篇非常有趣的文章!

标签: java arrays


【解决方案1】:

由于数组已排序,您可以循环遍历它们,随时检查重复项。这是一些伪代码:

//loop over both arrays at once
int arrayAIndex = 0;
int arrayBIndex = 0;
while (arrayAIndex < arrayA.length && arrayBIndex < arrayB.length) {
  if (arrayA[arrayAIndex] == arrayB[arrayBIndex]) {
    arrayAIndex++;
    arrayBIndex++;
  } else if (arrayA[arrayAIndex] > arrayB[arrayBIndex]) {
    addToResultB(arrayBIndex);
    arrayBIndex++;
  } else if (arrayB[arrayBIndex] > arrayA[arrayAIndex]) {
    addToResultA(arrayAIndex);
    arrayAIndex++;
  }
}

//clean up any elements which were not looked at during the above
while (arrayAIndex < arrayA.length) {
  addToResultA(arrayAIndex);
  arrayAIndex++;
}
while (arrayBIndex < arrayB.length) {
  addToResultB(arrayBIndex);
  arrayBIndex++;
}

【讨论】:

  • 好答案。如果列表很大,这是最有效的解决方案。
  • 假设列表已排序:)
  • 这与我现有的实现非常相似,但我在“清理”阶段苦苦挣扎。非常感谢您的提示!我想我的问题很快就能解决!
  • 没问题!如果此答案解决了您的问题,请接受它作为解决方案 =)
  • 请注意,如果一个列表比另一个列表足够大,我在上面的 cmets 中的方法会更快。
猜你喜欢
  • 1970-01-01
  • 2021-12-05
  • 1970-01-01
  • 2020-01-11
  • 1970-01-01
  • 2018-01-07
  • 1970-01-01
  • 1970-01-01
  • 2019-01-20
相关资源
最近更新 更多