Guava表ConcurrentModificationException

时间:2013-04-03 23:28:05

标签: java guava

我正在阅读一些使用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);
        }
    }
}

2 个答案:

答案 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);