【问题标题】:Is manually updating a for loop iterator bad practice?手动更新 for 循环迭代器是不好的做法吗?
【发布时间】:2013-10-30 02:52:07
【问题描述】:

我有一个程序可以遍历车辆坐标列表,然后对它们执行其他功能。我只是在寻找不太靠近的成对连续坐标。如果车辆长时间静止,则可能会有数千个连续坐标相互重叠。

一旦找到我的两个坐标,我就会手动更新我的迭代器 (i=j-1),这样我就不必重复检查成千上万个坐标。我的问题是,这是好的做法吗?还是有可行的替代方案?我在网上找不到任何这样的例子。我看到了“继续”语句,但这似乎需要额外的 if 语句,并且手动更新更“优雅”。

int LatLngSize = latLngList.size();
for (int i = 0; i < LatLngSize; i++) {
    j = i + 1;
    validPoints = true;
    if (LatLngSize > j) {
        latLng1.setCoordinate(latLngList.get(i));
        latLng2.setCoordinate(latLngList.get(j));
        consecutivePointDistance = latLng1.distance(latLng2);
    }
    while (consecutivePointDistance < 0.05) {
        j++;
        if (LatLngSize > j) {
            latLng2.setCoordinate(latLngList.get(j));
            consecutivePointDistance = latLng1.distance(latLng2);
            i = j - 1; // This is the potential offender.
        } else {
            validPoints = false;
            consecutivePointDistance = 100;
        }   
    }

    //Do stuff with my latlng1 and latlng2
}

【问题讨论】:

  • 它不是很漂亮,但它是有效的。通常,您可能会重写为 while 循环 - 然后根据条件以不同方式更新外部循环参数的事实更加明显。通常,for 循环预计每次都以相同的增量运行。它使您的代码更难遵循 - 因此更容易出现错误。
  • 我认为你不需要做这样的事情。看我的回答stackoverflow.com/questions/19672975/…

标签: java processing-efficiency


【解决方案1】:

是的。这是不好的做法。它会编译并运行得很好,但在回答你的问题时,这是不好的做法。

如果您想手动更新迭代器,请使用while 循环。

您可以使用for 循环执行的任何操作也可以使用while 循环执行。选择实际实现的循环是可读性的问题。在for 循环中,人们期望迭代器在更新语句中更新,并且只在更新语句中更新。

如果您不知道如何重写循环以使迭代器仅在更新语句中更新,请考虑以下内容:

for(int i=0; i<someValue; ++i /*i also updated at line 18*/)

仅作为示例。这仍然比重写代码更糟糕,因此它不会在第 18 行(或任何行)更新,但比在第 18 行更新它并且不在更新语句中留下注释要好得多。

或者,对于这个答案的每个 cmets,试试这个:

for(int i=0; i<someValue; /*see body*/) {
    //do stuff
    //update i
    //do stuff
}

现在在这种情况下,您的更新语句是完全空的,因此即使没有 /*see body*/ 注释,维护您的代码的任何人都已经知道 i 必须在正文中的某个位置进行修改。只需将 ++i 添加为 for 循环的最后一行,即可重新创建更新语句中的 ++i 行为。

【讨论】:

  • 我有时使用语法:for (int i = 0; i &lt; LatLngSize; /*see body*/ ) { /* modify i in here */ }
  • @DerFlatulator 哈哈,当你留下评论时,我一定一直在编辑它。我自己从来没有亲自这样做过,但是在发布我的答案后才想到。虽然,您的版本实际上有一个空的更新语句,这可能是最好的版本。
  • 我确实特别注意留下一个简短的评论,以确保阅读它的人注意到迭代值在循环体内被修改。不幸的是,人们看到了 for 循环并做出假设。
  • @nhgrif 我从来没有真正想过使用 while 循环。我一直认为 while 循环是“我想做一些事情直到某些事情发生变化”,而 for 循环是“我想遍历整个列表”......我还应该补充一点,这个 for 循环是嵌套在另一个 for 循环中,该循环遍历桥梁列表,以将车辆的位置与每个桥梁进行比较。通过使用两个 for 循环,我认为发生了什么更清楚了。但是重写一个while循环并不难。
  • @MattQuinlan 我通常以同样的方式考虑循环,但您可以将任何for 循环重写为while 循环,反之亦然。最后,一切都与可读性有关。如果它们同样是最优的,那么总是做最易读的。在 update 语句之外更新 for 循环迭代器会令人困惑,因此如果您绝对必须这样做,请在 update 语句应该在的位置留下评论。
【解决方案2】:

是的。这是一个不好的做法。不要这样做。如果我在维护你的代码,我明白了

for (int i = 0; i < latLngSize; i++)

我认为这意味着i 一次又一次地从 0 增加到 latLngSize。我不会进一步寻找i 更改的其他实例。所以,更改i 后果自负,前提是您不介意招致所有未来开发者的愤怒。

【讨论】:

    【解决方案3】:

    这不是你想要的吗?

    int size = latLngList.size();
    for (int i = 0; i + 1 < size; i++) {
        latLng1.setCoordinate(latLngList.get(i));
        latLng2.setCoordinate(latLngList.get(i+1));
        if(latLng1.distance(latLng2) >= 0.05) {
            //Do stuff with my latlng1 and latlng2
        }
    }
    

    【讨论】:

    • 是的,我可以简化提供的代码。即使从 1 开始迭代器也会有所帮助。目前这只是一项正在进行的工作,仍有待改进,我还不是最擅长编写代码。
    • Matt,是时候听到“过早的优化是万恶之源”这句话了。当真正获得工作/直截了当的草稿具有更高的优先级时,您担心再添加一条语句是否优雅。
    猜你喜欢
    • 2021-10-08
    • 2020-01-24
    • 2016-04-13
    • 2023-04-04
    • 2016-06-20
    • 2017-01-10
    • 2020-08-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多