在下面的代码中,我创建了一个新的ID,检查它是否存在,并返回它是否唯一:
private String generateNewId(List<Item> items) {
do {
String newId = ... // generateNewId from another method
if (items.stream.noneMatch(i -> i.getId().equals(newId))) {
return newId;
}
} while(true);
}
然而,我得到了PMD异常:
的异常
来自PMD文件:
我尝试将newId
变量移出循环,但随后得到了错误: lambda中使用的变量应该是最终变量,或者实际上是最终变量。
我如何重构我的代码以消除这些异常?还是我应该把这些警告压制为假阳性呢?
发布于 2020-06-20 10:15:02
您正在看到DD异常,因为当if条件计算为false时,变量newId
在do { } while(true)
循环中被重新定义。
不过,我认为DU异常是假阳性。在这种情况下,newId
总是至少使用一次:
如果项目列表为空,则如果项目列表不是空的,则返回nonMatch
,则在nonMatch
的闭包中使用newId
。
但是,这是PMD无法解决的问题,因为它不知道noneMatch
的语义。如果您将noneMatch
替换为anyMatch
,那么这将是一个真正的DU异常。
DD和DU异常通常很难修复,因为它们指出了更高层次上的设计问题。在这种情况下,问题不是变量newId
本身,而是do { } while(true)
的使用,这可能导致无限循环,因为您忽略了不能生成新的唯一id的情况。
解决这个问题的一种方法是解决这个问题:
private String generateNewId(List<Item> items) {
return Stream.generate(this::getRandomId)
.limit(100)
.filter(id -> isNew(id, items))
.findAny()
.orElseThrow(() -> new NoSuchElementException("Failed to generate unique id."));
}
private String getRandomId() {
return "4"; // chosen by fair dice roll.
// guaranteed to be random.
}
private boolean isNew(String id, List<Item> items) {
return items.stream().noneMatch(item -> id.equals(item.getId()));
}
此解决方案通过尝试生成一个新id最多100次来解决无限循环问题,并在失败时抛出异常。根据您的情况,您可以选择不同的限制。
https://stackoverflow.com/questions/62445530
复制相似问题