Java 中的迭代器模式:掌握顺序元素访问
大约 4 分钟
也称为
- 游标
迭代器设计模式的意图
Java 中的迭代器设计模式提供了一种方法,可以顺序访问聚合对象的元素,而无需暴露其底层表示。这种行为模式对于高效的集合遍历至关重要。
迭代器模式的详细解释及现实世界示例
现实世界示例
想象一下,您访问一个拥有大量藏书的图书馆,这些藏书按不同的类别进行组织,例如小说、非小说、科学等。与其自己搜索每个书架,不如让图书管理员为您提供每个类别特定的指南或数字目录。这个指南充当“迭代器”,允许您逐节浏览书籍,甚至跳到特定类型的书籍,而无需了解书籍在书架上的组织方式。每个指南负责遍历其部分,提供一种一致且高效的方式来访问书籍,就像迭代器设计模式为软件应用程序提供了一种统一的方法来遍历不同的数据结构。
通俗地说
Java 迭代器设计模式提供了一种方法,可以顺序访问集合的元素,而无需暴露其底层结构。这种模式在 Java 编程中被广泛用于高效的数据访问。
维基百科说
在面向对象编程中,迭代器模式是一种设计模式,其中使用迭代器来遍历容器并访问容器的元素。
Java 中迭代器模式的编程示例
我们 Java 迭代器设计模式示例中的主要类是包含物品的 TreasureChest
。这展示了如何在 Java 中实现和使用迭代器以实现高效的集合遍历。
public class TreasureChest {
private final List<Item> items;
public TreasureChest() {
items = List.of(
new Item(ItemType.POTION, "Potion of courage"),
new Item(ItemType.RING, "Ring of shadows"),
new Item(ItemType.POTION, "Potion of wisdom"),
new Item(ItemType.POTION, "Potion of blood"),
new Item(ItemType.WEAPON, "Sword of silver +1"),
new Item(ItemType.POTION, "Potion of rust"),
new Item(ItemType.POTION, "Potion of healing"),
new Item(ItemType.RING, "Ring of armor"),
new Item(ItemType.WEAPON, "Steel halberd"),
new Item(ItemType.WEAPON, "Dagger of poison"));
}
public Iterator<Item> iterator(ItemType itemType) {
return new TreasureChestItemIterator(this, itemType);
}
public List<Item> getItems() {
return new ArrayList<>(items);
}
}
这是 Item
类
public class Item {
private ItemType type;
private final String name;
public Item(ItemType type, String name) {
this.setType(type);
this.name = name;
}
@Override
public String toString() {
return name;
}
public ItemType getType() {
return type;
}
public final void setType(ItemType type) {
this.type = type;
}
}
public enum ItemType {
ANY, WEAPON, RING, POTION
}
Iterator
接口非常简单。
public interface Iterator<T> {
boolean hasNext();
T next();
}
在以下示例中,我们演示了不同类型的迭代器。
@Slf4j
public class App {
private static final TreasureChest TREASURE_CHEST = new TreasureChest();
private static void demonstrateTreasureChestIteratorForType(ItemType itemType) {
LOGGER.info("------------------------");
LOGGER.info("Item Iterator for ItemType " + itemType + ": ");
var itemIterator = TREASURE_CHEST.iterator(itemType);
while (itemIterator.hasNext()) {
LOGGER.info(itemIterator.next().toString());
}
}
private static void demonstrateBstIterator() {
LOGGER.info("------------------------");
LOGGER.info("BST Iterator: ");
var root = buildIntegerBst();
var bstIterator = new BstIterator<>(root);
while (bstIterator.hasNext()) {
LOGGER.info("Next node: " + bstIterator.next().getVal());
}
}
private static TreeNode<Integer> buildIntegerBst() {
var root = new TreeNode<>(8);
root.insert(3);
root.insert(10);
root.insert(1);
root.insert(6);
root.insert(14);
root.insert(4);
root.insert(7);
root.insert(13);
return root;
}
public static void main(String[] args) {
demonstrateTreasureChestIteratorForType(RING);
demonstrateTreasureChestIteratorForType(POTION);
demonstrateTreasureChestIteratorForType(WEAPON);
demonstrateTreasureChestIteratorForType(ANY);
demonstrateBstIterator();
}
}
程序输出
13:36:37.087 [main] INFO com.iluwatar.iterator.App -- ------------------------
13:36:37.089 [main] INFO com.iluwatar.iterator.App -- Item Iterator for ItemType RING:
13:36:37.089 [main] INFO com.iluwatar.iterator.App -- Ring of shadows
13:36:37.089 [main] INFO com.iluwatar.iterator.App -- Ring of armor
13:36:37.089 [main] INFO com.iluwatar.iterator.App -- ------------------------
13:36:37.089 [main] INFO com.iluwatar.iterator.App -- Item Iterator for ItemType POTION:
13:36:37.089 [main] INFO com.iluwatar.iterator.App -- Potion of courage
13:36:37.089 [main] INFO com.iluwatar.iterator.App -- Potion of wisdom
13:36:37.089 [main] INFO com.iluwatar.iterator.App -- Potion of blood
13:36:37.089 [main] INFO com.iluwatar.iterator.App -- Potion of rust
13:36:37.089 [main] INFO com.iluwatar.iterator.App -- Potion of healing
13:36:37.089 [main] INFO com.iluwatar.iterator.App -- ------------------------
13:36:37.089 [main] INFO com.iluwatar.iterator.App -- Item Iterator for ItemType WEAPON:
13:36:37.089 [main] INFO com.iluwatar.iterator.App -- Sword of silver +1
13:36:37.089 [main] INFO com.iluwatar.iterator.App -- Steel halberd
13:36:37.089 [main] INFO com.iluwatar.iterator.App -- Dagger of poison
13:36:37.089 [main] INFO com.iluwatar.iterator.App -- ------------------------
13:36:37.089 [main] INFO com.iluwatar.iterator.App -- Item Iterator for ItemType ANY:
13:36:37.089 [main] INFO com.iluwatar.iterator.App -- Potion of courage
13:36:37.089 [main] INFO com.iluwatar.iterator.App -- Ring of shadows
13:36:37.089 [main] INFO com.iluwatar.iterator.App -- Potion of wisdom
13:36:37.089 [main] INFO com.iluwatar.iterator.App -- Potion of blood
13:36:37.089 [main] INFO com.iluwatar.iterator.App -- Sword of silver +1
13:36:37.089 [main] INFO com.iluwatar.iterator.App -- Potion of rust
13:36:37.089 [main] INFO com.iluwatar.iterator.App -- Potion of healing
13:36:37.089 [main] INFO com.iluwatar.iterator.App -- Ring of armor
13:36:37.089 [main] INFO com.iluwatar.iterator.App -- Steel halberd
13:36:37.090 [main] INFO com.iluwatar.iterator.App -- Dagger of poison
13:36:37.090 [main] INFO com.iluwatar.iterator.App -- ------------------------
13:36:37.090 [main] INFO com.iluwatar.iterator.App -- BST Iterator:
13:36:37.090 [main] INFO com.iluwatar.iterator.App -- Next node: 1
13:36:37.090 [main] INFO com.iluwatar.iterator.App -- Next node: 3
13:36:37.090 [main] INFO com.iluwatar.iterator.App -- Next node: 4
13:36:37.090 [main] INFO com.iluwatar.iterator.App -- Next node: 6
13:36:37.090 [main] INFO com.iluwatar.iterator.App -- Next node: 7
13:36:37.090 [main] INFO com.iluwatar.iterator.App -- Next node: 8
13:36:37.090 [main] INFO com.iluwatar.iterator.App -- Next node: 10
13:36:37.090 [main] INFO com.iluwatar.iterator.App -- Next node: 13
13:36:37.090 [main] INFO com.iluwatar.iterator.App -- Next node: 14
何时在 Java 中使用迭代器模式
在 Java 中使用迭代器设计模式
- 访问聚合对象的内容,而无需暴露其内部表示。
- 支持对聚合对象进行多次遍历。
- 为遍历不同的聚合结构提供统一的接口。
迭代器模式 Java 教程
迭代器模式在 Java 中的现实世界应用
- Java Collections Framework 广泛使用迭代器,允许以不同的方式遍历集合。
- 数据库通常使用迭代器来导航通过 SQL 查询获取的数据记录。
- java.util.Iterator
- java.util.Enumeration
迭代器模式的优点和权衡
优点
- 减少了数据结构和用于迭代的算法之间的耦合。
- 为迭代各种类型的数据结构提供统一的接口,提高代码可重用性和灵活性。
权衡
- 使用迭代器对象的开销可能会略微降低性能,与直接遍历方法相比。
- 复杂的聚合结构可能需要复杂的迭代器,这些迭代器可能难以管理或扩展。