迭代 ImmutableSet 和 ImmutableList 并改变对象
Iterate over an ImmutableSet and ImmutableList and mutate objects
我有以下设置(即 Entity
是一个 JPA2
实体,entities
是一个集合)
class Entity {
Set<SubEntity> entities = new HashSet<>();
public Set<SubEntity> getEntities() {
return entities;
}
}
class SubEntity {
Double value;
// setters and getters ommitted
}
class SomeLibrary {
public static List<Double> transform(List<Double> values) {
// transform values and return a new list with transfored values
}
}
我需要使用外部库来转换 SubEntity
中的 value
字段,该库采用 List<Doubles>
和 returns 具有转换值的新列表。之后我需要用 transofmred 值更新 SubEntity
。
因为 Set
不保证迭代顺序我首先将它转换为 ImmutableSet
并使用 Collections2.transform
创建值的 ImmutableList
。
ImmutableSet<SubEntity> entities = ImmutableSet.copyOf(entity.getEntities());
ImmutableList<Double> values = ImmutableList.copyOf(Collections2.transform(entities, (e) -> e.getValue()))
此时我假设两个集合中的项目(entities
和 values
匹配,就像我压缩两个列表时一样)
List<Double> transformedValues = SomeLibrary.transform(values);
Iterator<SubEntity> entityIterator = entities.iterator();
Iterator<Double> valueIterator = transformedValues.iterator();
while(entityIterator.hasNext() && valueIterator.hasNext()) {
SubEntity entity = entityIterator.next();
Double value = valueIterator.next();
entity.setValue(value);
}
所以有两个问题:
- 我是否可以在迭代时安全地改变不可变集合中对象的字段?
- 当我迭代
SubEntity
的 ImmutableSet
和转换值的 List
时,我假设这些值匹配。当我使用不可变集合和 transform
函数时,这是否得到保证?
- 是的,除非双精度值用于计算实体的 hashCode,并且集合使用 hashCode。但我真的不明白你为什么在这里使用 Set ,为什么它需要是不可变的。只需使用
new ArrayList<>(entity.getEntities())
就足以获得可靠、一致的迭代顺序。
- 是的,因为 ImmutableSet 的 javadoc 说:一个高性能、不可变的集合,具有可靠的、用户指定的迭代顺序。
我有以下设置(即 Entity
是一个 JPA2
实体,entities
是一个集合)
class Entity {
Set<SubEntity> entities = new HashSet<>();
public Set<SubEntity> getEntities() {
return entities;
}
}
class SubEntity {
Double value;
// setters and getters ommitted
}
class SomeLibrary {
public static List<Double> transform(List<Double> values) {
// transform values and return a new list with transfored values
}
}
我需要使用外部库来转换 SubEntity
中的 value
字段,该库采用 List<Doubles>
和 returns 具有转换值的新列表。之后我需要用 transofmred 值更新 SubEntity
。
因为 Set
不保证迭代顺序我首先将它转换为 ImmutableSet
并使用 Collections2.transform
创建值的 ImmutableList
。
ImmutableSet<SubEntity> entities = ImmutableSet.copyOf(entity.getEntities());
ImmutableList<Double> values = ImmutableList.copyOf(Collections2.transform(entities, (e) -> e.getValue()))
此时我假设两个集合中的项目(entities
和 values
匹配,就像我压缩两个列表时一样)
List<Double> transformedValues = SomeLibrary.transform(values);
Iterator<SubEntity> entityIterator = entities.iterator();
Iterator<Double> valueIterator = transformedValues.iterator();
while(entityIterator.hasNext() && valueIterator.hasNext()) {
SubEntity entity = entityIterator.next();
Double value = valueIterator.next();
entity.setValue(value);
}
所以有两个问题:
- 我是否可以在迭代时安全地改变不可变集合中对象的字段?
- 当我迭代
SubEntity
的ImmutableSet
和转换值的List
时,我假设这些值匹配。当我使用不可变集合和transform
函数时,这是否得到保证?
- 是的,除非双精度值用于计算实体的 hashCode,并且集合使用 hashCode。但我真的不明白你为什么在这里使用 Set ,为什么它需要是不可变的。只需使用
new ArrayList<>(entity.getEntities())
就足以获得可靠、一致的迭代顺序。 - 是的,因为 ImmutableSet 的 javadoc 说:一个高性能、不可变的集合,具有可靠的、用户指定的迭代顺序。