【问题标题】:How to modify all elements except the current one when iterating迭代时如何修改除当前元素之外的所有元素
【发布时间】:2014-06-13 14:59:05
【问题描述】:

我有一个包含标签列表的评论列表。

我想遍历我的评论列表,如果一个评论有标签 DEPRECATE_OTHERS,我想添加一个标签 DEPRECATED 到所有其他 cmets。

到目前为止,我已经能够想出一个过于杂乱的解决方案,但我想知道是否有一些工具可以帮助我使其更清洁:

    for (int i = 0; i < comments.size(); i++) {
        Comment comment = comments.get(i);
        for (Tag tag : comment.getTags()) {
            if(MyEnum.DEPRECATE_OTHERS.equals(tag)) {
                for(int j = 0; j < comments.size(); j++) {
                    if(j != i) {
                        comments.get(j).getTags().add(MyEnum.DEPRECATED)
                    }
                }
            }
        }
    }

OBS:我可能有多个 DEPRECATE_OTHERS,在这种情况下我想添加多个 DEPRECATED 标志

【问题讨论】:

  • 我不确定我现在明白了。假设两个 cmets 有DEPRECATE_OTHERS。所有其他 cmets 是否应该获得两个 DEPRECATED 标签,而这些标签各获得一个?还是应该有 DEPRECATE_OTHERS 的 cmets 永远不会有 DEPRECATED 标签?
  • 对于我找到的每个 DEPRECATE_OTHERS,我必须将 DEPRECATED 添加到所有其他标签。原因是我的 Tag 类型比我在练习中描述的更复杂。
  • 如果两个 cmets (A, B) 有 DEPRECATE_OTHERS 他们是否有 DEPRECATED 标签? (因为 A DEPRECATE_OTHERS 使 B 弃用,对于 B 到 A 也是如此)
  • 听起来我的回答可能会奏效。
  • 是的,马可,你是对的。

标签: java collections


【解决方案1】:

您可以使用几种方法来简化此代码。对每次迭代使用Collection.contains() 和对象相等性,您可以将其归结为:

for (Comment comment : comments) {
    if(comment.getTags().contains(MyEnum.DEPRECATE_OTHERS))) {
        for (Comment otherComment : comments) {
            if (otherComment != comment) {
                otherComment.getTags().add(MyEnum.DEPRECATED)
            }
        }
    }
}

正如亚当所说,两个单独的迭代会更整洁。

【讨论】:

  • 你的看起来好多了,所以我要投赞成票。双循环背后的唯一理由是,在 BEST CASE 复杂性中,第一个评论有 deprecate others 标签,而且它是唯一的一个。在这种情况下,只需要一次完整的迭代。
【解决方案2】:

设置一个标志,例如deprecate_others_id = -1; 当您找到 DEPRECATE_OTHERS 标记时,将该变量设置为索引,当该变量不是 -1 时,将每个标记设置为 DEPRECATE_OTHERS。在您的迭代结束时,从头开始一个新的循环,该循环一直迭代直到到达deprecate_others_id,并在此过程中标记所有这些。

这利用了你当前正在迭代的事实,只会让你在启动Deprecate_Others的标签之前圈回标签

int deprecate_others_id = -1;
int numtags = 0;
for (int i = 0; i < comments.size(); i++) {
    Comment comment = comments.get(i);
    if(deprecate_others_id != -1){
        while(comment.getNumberofDepTags < numtags){
           comment.addTag(DEPRECATED);
        }
    }
    for (Tag tag : comment.getTags()) {
        if(MyEnum.DEPRECATE_OTHERS.equals(tag)) {
            deprecate_others_id = Math.max(deprecate_others_id,i);
        }
    }
}
if(deprecate_others_id != -1){
    for(int i=0; i<deprecate_others_id; i++){
      Comment comment = comments.get(i);
      while(comment.getNumberofDepTags < numtags){
           comment.addTag(DEPRECATED);
      }
    }
}

【讨论】:

  • 同意,我已经考虑过了,问题是我可能有多个 DEPRECATE_OTHERS,在这种情况下我想添加多个 DEPRECATED 标志。 (我的标签结构比字符串更复杂)。
  • 但如果您将 DEPRECATED 添加到所有其他评论,那么这仍然有效。只需存储 id 的 Math.max() 和要添加的 DEPRECATED 标签的数量。在第二个循环中,迭代到最大 id,添加标签,直到每个评论都有 numtags 已弃用标签数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-08
  • 2018-06-14
  • 1970-01-01
  • 2011-03-09
  • 1970-01-01
  • 1970-01-01
  • 2020-05-10
相关资源
最近更新 更多