我正在阅读一些使用Guava表的代码并偶尔抛出一个ConcurrentModificationException
- 我理解这一点,因为我正在迭代Table的列并在同一个循环中修改表。有没有一个干净/高效的方法来解决这个问题?我可以做一个表。在推出之前删除它并期望它能够工作吗?
final Set<Optional<SimpleWorkDataValue>> columnKeys = table.columnKeySet();
for (final SimpleWorkDataValue timeSeriesValue : timeSeriesValues) {
final Optional<SimpleWorkDataValue> rowKey = Optional.of(timeSeriesValue);
for (final Optional<SimpleWorkDataValue> columnKey : columnKeys) {
if (!table.contains(rowKey, columnKey)) {
table.put(rowKey, columnKey, ResultSet.EMPTY);
}
}
}
答案 0 :(得分:4)
根据嵌套循环的典型执行中涉及的行,列和单元计数,您可以通过将在此代码行中隐式实例化的Iterator分解出来来节省内存:
for (final Optional<SimpleWorkDataValue> columnKey : columnKeys) {
由于此Iterable在整个过程中不会更改,因此您可以在开头将列键复制到List,然后在内部循环中迭代它:
final List<Optional<SimpleWorkDataValue>> columnKeyList =
ImmutableList.copyOf(table.columnKeySet());
for (final SimpleWorkDataValue timeSeriesValue : timeSeriesValues) {
final Optional<SimpleWorkDataValue> rowKey = Optional.of(timeSeriesValue);
for (final Optional<SimpleWorkDataValue> columnKey : columnKeyList) {
if (!table.contains(rowKey, columnKey)) {
table.put(rowKey, columnKey, ResultSet.EMPTY);
}
}
}
当然,这应该消除所有ConcurrentModificationExceptions
答案 1 :(得分:1)
详细说明我的评论:
//a temporary table
Table<Optional<SimpleWorkDataValue>, Optional<SimpleWorkDataValue>, Object> temp =
HashBasedTable.create();
for (final SimpleWorkDataValue timeSeriesValue : timeSeriesValues) {
final Optional<SimpleWorkDataValue> rowKey = Optional.of(timeSeriesValue);
for (final Optional<SimpleWorkDataValue> columnKey : columnKeys) {
if (!table.contains(rowKey, columnKey)) {
//here add to temp instead of table
temp.put(rowKey, columnKey, ResultSet.EMPTY);
}
}
}
//after loop, put everyting back into table
table.putAll(temp);