0

我正在阅读一些使用 Guava 表的代码,偶尔会抛出一个ConcurrentModificationException- 我理解这是因为我正在遍历表的列并在同一个循环中修改表。有没有一种干净/高效的方法来解决这个问题?我可以在 put 之前做一个 table.remove 并期望它工作吗?

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);
        }
    }
}
4

2 回答 2

4

根据嵌套循环的典型执行所涉及的行、列和单元格计数,您可以通过分解在此代码行中隐式实例化的迭代器来节省内存:

    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

于 2013-04-03T23:54:34.423 回答
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);
于 2013-04-03T23:47:27.657 回答