Java中的Lambda:查找重复id并引发异常

Java中的Lambda:查找重复id并引发异常,java,spring,lambda,filter,stream,Java,Spring,Lambda,Filter,Stream,如果列表中使用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.equal

如果列表中使用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
    }
}


但它不起作用,我认为有一个更好的方法使用.orelsetrow->。那么,如果有多个uuid,如何检查carUuidList并抛出错误?

一种方法是基于给定列表创建一个集合,然后比较它们的大小。如果列表大于集合,则存在重复项。否则就没有了。下面是它在实践中的表现

final Set<UUID> uuidSet = new HashSet<>(carUuidList);
if (uuidSet.size() != carUuidList.size())
    throw new IllegalStateException("Duplicate UUIDs found.");

此解决方案以线性时间运行。

一种方法是基于给定列表创建一个集合,然后比较它们的大小。如果列表大于集合,则存在重复项。否则就没有了。下面是它在实践中的表现

final Set<UUID> uuidSet = new HashSet<>(carUuidList);
if (uuidSet.size() != carUuidList.size())
    throw new IllegalStateException("Duplicate UUIDs found.");

此解决方案以线性时间运行。

我建议创建第二个列表,其中仅包含使用流的唯一UUID,如本例所示:

最终列表distinctcaruidlist=carUuidList.stream 不同的 .toList; 之后,您可以比较两个列表的大小,如果大小不同,则引发异常:

ifdistinctcaruidlist.size!=carUuidList.size{ 抛出新的非法状态异常; }
我建议创建第二个列表,其中仅包含使用流的唯一UUID,如本例所示:

最终列表distinctcaruidlist=carUuidList.stream 不同的 .toList; 之后,您可以比较两个列表的大小,如果大小不同,则引发异常:

ifdistinctcaruidlist.size!=carUuidList.size{ 抛出新的非法状态异常; }
一个java 9+解决方案,具有短路HashSet::add,而不是迭代整个列表的新HashSetlist:

List<UUID> carUuidList = carRepository.getUuidList(); 

carUuidList.stream()
           .dropWhile(new HashSet<>()::add)
           .findFirst()
           .ifPresent(dup -> {throw new IllegalArgumentException("duplicate found: " + dup);} );

一个java 9+解决方案,具有短路HashSet::add,而不是迭代整个列表的新HashSetlist:

List<UUID> carUuidList = carRepository.getUuidList(); 

carUuidList.stream()
           .dropWhile(new HashSet<>()::add)
           .findFirst()
           .ifPresent(dup -> {throw new IllegalArgumentException("duplicate found: " + dup);} );

你确定你需要一辆lambda吗?您可以假设,如果列表中有所有唯一的ID,则此列表中的哈希集将具有相同的大小

if (carUuidList.size() != new HashSet<>(carUuidList).size())
   //throw exception 

你确定你需要一辆lambda吗?您可以假设,如果列表中有所有唯一的ID,则此列表中的哈希集将具有相同的大小

if (carUuidList.size() != new HashSet<>(carUuidList).size())
   //throw exception 

使用流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");

使用流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");

你说不工作是什么意思?您得到了错误的结果?@talex Operator'>'不能应用于'java.util.List','int'carUuidList.stream.filterc->c.equalscarUuid.collectors.toList.size>1可能是您想要的结果?您正在将UUID列表与int进行比较。我认为,您应该使用carUuidList.stream…collect…size>1a List不是int,因此无法进行比较。您将过滤后的UUID列表收集到一个列表中,然后将其与int进行比较。基本上,您需要在大小比较中使用.size。您所说的不起作用是什么意思?您得到了错误的结果?@talex Operator'>'不能应用于'java.util.List','int'carUuidList.stream.filterc->c.equalscarUuid.collectors.toList.size>1可能是您想要的结果?您正在将UUID列表与int进行比较。我认为,您应该使用carUuidList.stream…collect…size>1a List不是int,因此无法进行比较。您将过滤后的UUID列表收集到一个列表中,然后将其与int进行比较。基本上,您需要在大小比较中使用.size。我认为使用Set更直观。当然,在您的解决方案中,您可能可以使用.equals方法,因为两个对象都是List类型,而不是它们各自的大小。我认为这是个人的偏好。我认为最重要的是一个好的变量命名。使用.equals时,如果两个列表的排序方式不同,则存在风险。是的,Set似乎更好。非常感谢。@csalmhof这是一个风险是的。真不敢相信我竟然忘了!很高兴不时被提醒细节:我认为使用集合更直观一些。当然,在您的解决方案中,您可能可以使用.equals方法,因为两个对象都是List类型,而不是它们各自的大小。我认为这是个人的偏好。我认为最重要的是一个好的变量命名。使用.equals时,如果两个列表的排序方式不同,则存在风险。是的,Set似乎更好。非常感谢。@csalmhof这是一个风险是的。真不敢相信我竟然忘了!很高兴不时被提醒细节:非常感谢,投票通过。非常感谢,投票通过。非常感谢,但是如果caruuidleist.size!=新的HashSetcarUuidList.size更简单,也更容易理解那里发生了什么。我不明白为什么Java会带来新功能,带来更复杂、更长、性能相同的解决方案。非常感谢,但是如果carUuidList.size!=新的HashSetcarUuidList.size更简单,也更容易理解那里发生了什么。我不明白为什么Java带来了更复杂、更长的解决方案的新特性 他有同样的表现。