You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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自身的业务方法...
}

方案优势

  1. 完全隐藏内部实现:对外仅暴露Iterator标准接口,调用者无法直接操作内部的卡牌集合,避免了内部存储结构的泄露。
  2. 支持多遍历方式:通过不同方法返回对应逻辑的迭代器,满足顺序、随机、逆序等多种遍历需求,后续还可轻松扩展其他遍历规则。
  3. 符合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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 15:13:38