Java中为Deck类实现多种迭代方式并隐藏内部实现的最优方案
背景
我有如下代表一副卡牌的Deck类,内部包含一个Card类型的List:
public class Deck { private List<Card> cards = new ArrayList<Card>(); ... }
问题
我希望能够以不同方式遍历Deck类,例如按顺序、随机顺序等,同时尽可能隐藏该类的内部实现细节。
已尝试方案
实现
Iterable<Card>接口
若按如下方式让Deck类实现Iterable接口:public class Deck implements Iterable<Card> { private List<Card> cards = new ArrayList<Card>(); @Override public Iterator<Card> iterator() { ... } ... }该方式仅支持一种遍历
Deck的方式。返回不同顺序的数组副本
例如,随机顺序的实现:public class Deck { private List<Card> cards = new ArrayList<Card>(); public List<Card> randomOrder() { List<Card> copy = new ArrayList<Card>( cards ); Collections.shuffle(copy); return copy; } ... }这种方式看似最简单,但会过多暴露类的内部实现细节。
求助
请问实现该需求的最优方案是什么?
最优方案:提供多迭代器方法+保留默认Iterable实现
方案实现
让Deck实现Iterable<Card>作为默认遍历(顺序遍历),同时提供多个返回不同Iterator的方法,支持随机、逆序等多种遍历逻辑:
import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; public class Deck implements Iterable<Card> { private List<Card> cards = new ArrayList<>(); // 默认顺序遍历的迭代器 @Override public Iterator<Card> iterator() { // 返回内部列表的迭代器,仅暴露迭代接口而非集合本身 return cards.iterator(); } // 随机遍历的迭代器 public Iterator<Card> randomIterator() { List<Card> shuffledCopy = new ArrayList<>(cards); Collections.shuffle(shuffledCopy); return shuffledCopy.iterator(); } // 扩展:逆序遍历的迭代器 public Iterator<Card> reverseIterator() { List<Card> reversedCopy = new ArrayList<>(cards); Collections.reverse(reversedCopy); return reversedCopy.iterator(); } // 其他Deck自身的业务方法... }
方案优势
- 完全隐藏内部实现:对外仅暴露
Iterator标准接口,调用者无法直接操作内部的卡牌集合,避免了内部存储结构的泄露。 - 支持多遍历方式:通过不同方法返回对应逻辑的迭代器,满足顺序、随机、逆序等多种遍历需求,后续还可轻松扩展其他遍历规则。
- 符合Java迭代规范:默认实现
Iterable可直接用于增强for循环,自定义迭代器也遵循标准API,调用方式统一。
使用示例
Deck deck = new Deck(); // 默认顺序遍历 for (Card card : deck) { // 处理顺序卡牌 } // 随机遍历 Iterator<Card> randomIter = deck.randomIterator(); while (randomIter.hasNext()) { Card card = randomIter.next(); // 处理随机卡牌 } // Java 8+ 可通过lambda在增强for中使用自定义迭代器 for (Card card : () -> deck.reverseIterator()) { // 处理逆序卡牌 }
可选优化(Java 8+)
如果需要支持流操作,可以为每种遍历方式添加流返回方法:
public Stream<Card> randomStream() { List<Card> shuffledCopy = new ArrayList<>(cards); Collections.shuffle(shuffledCopy); return shuffledCopy.stream(); }
调用者可直接结合流API进行过滤、映射等操作,灵活性更强。
内容的提问来源于stack exchange,提问作者thomaoc
相关产品推荐
相关产品推荐

