我想使用 lambda 表达式检查一个列表,如果列表中有多个 ID,则抛出异常:
final List<UUID> carUuidList = carRepository.getUuidList();
for (int i = 0; i < carUuidList.size(); i++) {
final UUID carUuid = carUuidList.get(i);
if(carUuidList.stream().filter(c -> c.equals(carUuid)).collect(Collectors.toList()) > 1){
//throw exception
}
}
但是它不起作用,我认为有更好的方法使用
.orElseThrow(() -> ... ())
。那么,如果有多个 uuid,如何检查 carUuidList
并抛出错误?
您确定需要 lambda 吗?您可以假设如果列表中存在所有唯一的 id,则该列表中的 HashSet 将具有相同的大小。
if (carUuidList.size() != new HashSet<>(carUuidList).size())
//throw exception
Java 9+ 解决方案,使用短路
HashSet<>()::add
而不是 new HashSet<>(list)
来迭代整个列表:
List<UUID> carUuidList = carRepository.getUuidList();
carUuidList.stream()
.dropWhile(new HashSet<>()::add)
.findFirst()
.ifPresent(dup -> {throw new IllegalArgumentException("duplicate found: " + dup);} );
我建议创建第二个列表,其中仅包含使用流的唯一 uuid,如本示例所示:
final List<UUID> distinctCarUuidList = carUuidList.stream()
.distinct()
.collect(Collectors.toList());
之后你可以比较两个列表的大小,如果大小不同则抛出异常:
if(distinctCarUuidList.size() != carUuidList.size()) {
throw new IllegalStateException();
}
使用 Stream API 的另一种替代解决方案:
if (IntStream.rangeClosed(0, carUuidList.size()-1)
.anyMatch(i -> IntStream.rangeClosed(0, carUuidList.size()-1)
.filter(j -> j != i)
.anyMatch(j -> carUuidList.get(i).equals(carUuidList.get(j)))))
throw new Exception("Duplicates found");
一种方法是根据给定的
Set
创建一个 List
,然后比较它们的大小。如果 List
大于 Set
,则存在重复项。不然就没有了。这是它在实践中的样子。
final Set<UUID> uuidSet = new HashSet<>(carUuidList);
if (uuidSet.size() != carUuidList.size())
throw new IllegalStateException("Duplicate UUIDs found.");
该解决方案以线性时间运行。