如何修复声纳问题 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());
}
声纳检测到我的代码有违规行为“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());
}