如何修复声纳问题 squid:ForLoopCounterChangedCheck?

How to fix sonar issue squid:ForLoopCounterChangedCheck?

声纳检测到我的代码有违规行为“for”循环停止条件应该是不变的。 我试图修复它,但声纳认为问题仍然存在,因为我的 for 循环在另一个 for 循环中。

这是代码片段:

int limit = Const.getBatchLimit();
int count = 0;

for (int paramIndex = 0; paramIndex < paramList.size();)
{
    List<Param> tempParam = new ArrayList<>();
    StringBuilder retrieveMsg = new StringBuilder("Retrieving: \n");
    for (count = 0; (count < limit) && (paramIndex < param.size()); count++, paramIndex++)
    {
        Param myParam = paramList.get(paramIndex);
        retrieveMsg.append(myParam .seq()).append(Str.SLASH).append(Str.CRLF);
        tempParam.add(myParam);
    }
    LOGGER.info(retrieveMsg.toString());

    LOGGER.info("Done. Retrieved count: " + tempParam.size());
}

我无法将 paramIndex++ 移动到第一个 for 循环,因为行为将与期望的不同。

如果有人可以就如何解决此违规问题提出建议,我们将不胜感激。 提前谢谢你。

将参数列表拆分为 limit 大小的块是一种有趣的方法,但它可能完全摆脱嵌套循环。

此外,如果 tempParam 仅用于跟踪批次中的元素数量,则可以通过重用 count 来替换它。

int limit = Const.getBatchLimit();

StringBuilder retrieveMsg = new StringBuilder("Retrieving: \n");

for (int i = 0, count = 1, n = paramList.size(); i < n; i++, count++) {
    Param myParam = paramList.get(i);
    retrieveMsg.append(myParam.seq()).append(Str.SLASH).append(Str.CRLF);

    if (count % limit == 0 || i == n - 1) {
        LOGGER.info(retrieveMsg.toString());
        LOGGER.info("Done. Retrieved count: " + count);
        retrieveMsg = new StringBuilder("Retrieving: \n");
        count = 0;
    }
}

或者可以完全重构此代码以使用 Java Stream API 并实现一个辅助方法来处理块(例如 printChunk):

int chunks = paramList.size() / limit + (paramList.size() % limit == 0 ? 0 : 1);
IntStream.range(0, chunks)
         .mapToObj(i -> paramList.subList(i * limit, Math.min((i + 1) * limit, paramList.size()))) // getting stream of sublists
         .forEach(MyClass::printChunk);

// ...
static void printChunk(List<Param> chunk) {
    StringBuilder msg = new StringBuilder("Retrieving:\n");
    chunk.forEach(p -> msg.append(p.seq()).append(Str.SLASH).append(Str.CRLF));

    LOGGER.info(msg.toString());
    LOGGER.info("Done. Retrieved count: " + chunk.size());
}