比较 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);
我需要在不使用嵌套 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);