密钥集迭代器的低效使用¶
ID: java/inefficient-key-set-iterator
Kind: problem
Security severity:
Severity: recommendation
Precision: high
Tags:
- efficiency
- maintainability
Query suites:
- java-security-and-quality.qls
Java 的集合框架提供了多种遍历映射内容的方法。您可以检索键集、值集合或“条目”集(实际上是键/值对)。
迭代器的选择会影响性能。例如,如果循环体对每个检索到的键执行映射查找,则迭代映射的键集被认为是不良做法。
建议¶
评估循环体的要求。如果它除了在映射中查找之外实际上不需要键,则迭代映射的值(通过调用 values
获得)即可。如果循环确实需要映射中每个映射的键和值,则迭代条目集(通过调用 entrySet
获得)并从每个条目中检索键和值。这每次都会节省更昂贵的映射查找。
示例¶
在以下示例中,方法 findId
的第一个版本使用键集迭代映射 people
。这是低效的,因为循环体需要访问每个键的值。相比之下,第二个版本使用条目集迭代映射,因为循环体需要每个映射的键和值。
// AVOID: Iterate the map using the key set.
class AddressBook {
private Map<String, Person> people = ...;
public String findId(String first, String last) {
for (String id : people.keySet()) {
Person p = people.get(id);
if (first.equals(p.firstName()) && last.equals(p.lastName()))
return id;
}
return null;
}
}
// GOOD: Iterate the map using the entry set.
class AddressBook {
private Map<String, Person> people = ...;
public String findId(String first, String last) {
for (Entry<String, Person> entry: people.entrySet()) {
Person p = entry.getValue();
if (first.equals(p.firstName()) && last.equals(p.lastName()))
return entry.getKey();
}
return null;
}
}
参考¶
Java API 规范:Map.entrySet()。