如何检测列表是否已更改?

diz*_*iaq 6 java hash mutable

List在一个由鲜为人知的专有框架管理的类中有一个字段。

注释@BindMagic由框架管理,因此底层列表有时会发生变化:它可能会被重新创建或其元素可能会发生变化。

class SharedEntity{

  @BindMagic // this annotation does a magic that we cannot control
  private List<Map<String,Object>> values;

  public boolean isChangedSincePreviousCall(){
    // check if "values" have changed since the previous call of this method          
  }
}
Run Code Online (Sandbox Code Playgroud)

我同意这是一个糟糕的设计,但让我们假设没有可能影响它。

不时(不是在每个突变上)需要检查列表是否已更改。例如,我想用 method 来做isChangedSincePreviousCall。也许,像哈希和这样的东西会很好。但我很好奇有没有更好的方法。

检测列表是否更改的最佳做法是什么?

Boh*_*ian 1

使用哈希值并不是确定的,因为可以从不同的输入生成相同的哈希值,尽管可能性很小。

“改变”和“与众不同”意味着不同的事情。考虑其中一个映射中的一个条目,该条目在对您的方法的调用之间从"A" -> 1"A" -> 2又从 到再次更改 - 它已更改但没有不同。我假设你的意思是“不同”。"A" -> 1

检查时复制一份,并与当前状态进行比较。假设映射值是不可变的

class SharedEntity {

    @BindMagic
    private List<Map<String, Object>> values;
    private List<Map<String, Object>> valuesCopy;

    public boolean isChangedSincePreviousCall() {
        newCopy = new ArrayList<>(values);
        boolean result = !Objects.equals(valuesCopy, newCopy);
        valuesCopy = newCopy;
        return result;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果 Map 值是(或包含)可变对象,则在创建副本时必须对其进行深层复制。

仅供参考,如果两个参数都为空,Objects#equals()则返回。true