从 Java 基础到掌握 — 第 5 集
选择适合您目的的泛型和集合
该博客上撰写的文章是出于教学目的而创建的。 另外,文章中的信息可能不正确,请谨慎。
Java集合存储各种数据,但每种数据结构做不同的事情。 如果一起使用泛型,则可以在编译时检查类型错误,而不必每次都转换检索到的值。
List, Set, Map
List<String> party = new ArrayList<>();
Set<Integer> unlockedIds = new HashSet<>();
Map<Integer, Item> itemById = new HashMap<>();
party.add("Rose");
unlockedIds.add(10);
itemById.put(10, new Item(10, "Potion"));
List 允许排序和重复,而 Set 处理非重复值的存在或不存在。 Map通过键来查找值。
HashMap的顺序不保证。 如果排序或输入顺序是一个合同,您应该选择适合该目的的实现。
安全搜索
Item item = itemById.get(10);
if (item != null) {
System.out.println(item.getName());
}
如果键不存在,则 get 返回 null。 避免将 null 本身存储为值的设计可以防止 None 和 null 值之间的混淆。
泛型类
public final class Registry<T extends Identifiable> {
private final Map<Integer, T> values = new HashMap<>();
public void add(T value) {
values.put(value.getId(), value);
}
public Optional<T> find(int id) {
return Optional.ofNullable(values.get(id));
}
}
T extends Identifiable 是一个限制,即要存储的类型必须提供 ID。 Registry<Item> 和 Registry<Monster> 复用相同的规则,但值不混合。
依赖接口而不是实现
如果将字段和参数类型设置为List或Map接口,则合约中仅保留必要的操作。 但是,如果性能特征很重要,您还应该知道实际实现是 ArrayList 还是 LinkedList。
集合选择不仅仅是数据数量的问题。 首先必须确定使用目的,例如顺序、重复、搜索关键字和更改频率。