I have a List
field in a class managed by a little-known proprietary framework.
The annotation @BindMagic
is managed by the framework, so the underlying list mutates sometimes: it could be recreated or its elements could change.
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
}
}
I'm agree that it is a poor design, but let's suppose there's no possibility to affect it.
Time to time (not on every mutation) it's needed to check if the list is changed. For instance, I want do it with the method isChangedSincePreviousCall
.
Probably, something like a hash sum would be good. But I'm curious are there better ways.
What is the best practice to detect if the list is changed?
Using a hash is not definitive, because the same hash can be produced from different inputs, albeit with a very small chance.
"Being changed" and "being different" mean different things. Consider an entry in one of the maps that is changed from "A" -> 1
to "A" -> 2
then back to "A" -> 1
again between calls to your method - it was changed but isn't different. I'll assume you mean "different".
Make a copy when checking and compare that with the current state. Assuming that the map values are immutable:
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;
}
}
If the Map values are (or contain) mutable objects, you'll have to make a deep copy of them when creating the copy.
FYI Objects#equals()
returns true
if both parameters are null.