比较 Java 中不同列表中的两个不同对象

Compare two different objects in different lists in Java

我需要在不使用嵌套 for 循环的情况下检查列表 A 中的对象是否存在于列表 B 中,因为如果列表的大小很大,则需要花费太多时间。

这是我的代码:

for(Person el : persons)
{
    for(Client in : clients)
    {
        if(el.getIdentifier() == in.getTire().getIdentifier())
        {
            exists=true;
            break;
        }
    }
}

如何在不使用循环和中断的情况下获得相同的结果?

您可以通过使用更适合快速查找的数据结构来提高性能。如果您将客户端存储在 HashMap 中,其中键是标识符,值是客户端对象,那么您的代码将变为:

for(Person el : persons)
{
    if (clients.containsKey(el.getIdentifier()) {
      exists=true;
    }
}

现在你只有一个循环,在 hashmap 中查找的成本是 O(1)。

经典呢:

contains(Object o) //Returns true if this list contains the specified element.

所以你可以只做循环:

for(Person el : persons)
{

        if(clients.contains(el.getIdentifier()))
        {
            exists=true;
            break;
        }        
}

但是查看您的代码,根据您的目标,您可以使用:

containsAll(Collection c)
       //   Returns true if this list contains all of the elements of the specified collection.

也许你可以这样做

Set<String> identifierSet = new HashSet<>();

for (Person el : persons) {
    identifierSet.add(el.getIdentifier());
}

for (Client in : clients) {
    if (identifierSet.contains(in.getTire().getIdentifier())) {
        exists = true;
        break;
    }
}

这会将代码的复杂度从 O(NxM) 更改为 O(N+M):

    Set<Integer> personIds = persons.stream()
            .map(e -> e.getIdentifier())
            .collect(Collectors.toCollection(HashSet::new));

    boolean exists = clients.stream().anyMatch(
            c -> personIds.contains(c.getTire().getIdentifier()));

anyMatch所述,基于StreamAPI可以提供如下解决方案(假设标识符类型为String):

// prepare set of identifiers in clients
Set<String> clientIds = clients
    .stream()                                // Stream<Client>
    .map(in -> in.getTire().getIdentifier()) // Stream<String> client ids
    .collect(Collectors.toSet());

boolean anyPersonIsClient = persons
   .stream()                    // Stream<Person>
   .map(Person::getIdentifier)  // Stream<String> person identifiers
   .anyMatch(clientIds::contains);

boolean allPersonsAreClient = persons
   .stream()                    // Stream<Person>
   .map(Person::getIdentifier)  // Stream<String> identifiers
   .allMatch(clientIds::contains);