在一个列表中统计一个对象的出现次数。

3

我试图在列表中计算一个对象的出现次数,但似乎不起作用。

这是我的类 Card:

public class Card {
    private int value;
    private String type;
    private String color; 
}

我正在尝试设置一副104张牌的卡组,其中包含每张牌的2个实例,但看起来我的条件不正确:

public static List<Card> InitializeDeck(){
        for(int i=0;i<104;i++){
            boolean isOk = true;
            while (isOk){
                int col = (int) (Math.floor(Math.random() * 2) + 1);
                if (col == 1) {
                    color = "Black";
                } else {
                    color = "Red";
                }

                value = (int) (Math.floor(Math.random() * 14));
                while (value == 0) {
                    value = (int) (Math.floor(Math.random() * 14));
                }

                int ty = (int) (Math.floor(Math.random() * 4));
                switch (ty) {
                    case 0:
                        type = "Spade";
                        break;
                    case 1:
                        type = "Heart";
                        break;
                    case 2:
                        type = "Diamond";
                        break;
                    case 3:
                        type = "Club";
                        break;
                }
                Card card = new Card(value, type, color);
                if(deck.isEmpty() || deck.stream().filter(line -> card.equals(line)).count()<=1){
                    deck.add(card);
                    isOk=false;
                }
            }

        }

        return deck;
    }

我得到了一副104张牌的牌组,但有时同一张牌会出现4次,甚至可能没有任何一次出现,有什么提示吗?


你是如何构建那个牌组的?如果你只是迭代52张可能的牌,每张牌都加入两次,最后洗牌,那么你应该不会出现不想要的重复(并且你可以确保每张牌恰好包含两次)。你检查重复出现的方法意味着你要么随机选择卡牌,要么让用户构建牌组。 - Thomas
1
你在你的Card类中重写了equals()方法吗? - Benjamin Urquhart
我编辑并添加了代码。我基于随机数构建它,这就是为什么我想检查一张牌是否生成超过两次的原因。 - OthK
@Thomas 哦,你说得对,起初我还以为这是一个好方法,现在不行了,哈哈。 - OthK
1
@OthK 嗯,2种颜色,4种类型和13个值已经可以提供104种不同的组合。你确定你想要这样做,并且还要加上两张牌吗? - Thomas
显示剩余15条评论
1个回答

5

我会简单总结一下您问题的评论,并给出一个无需随机数且使用枚举类型来构建卡组的简单示例。

首先,我们定义枚举类型:

enum Color {
  RED,
  BLACK;
}

enum CardType {
  SPADE, //as per Yassin's comments you'll probably want to define the type's color later on
  HEART, //you'd then use HEART(Color.RED) etc. - and provide the correct constructor
  DIAMOND,
  CLUB;
}

Card类:

class Card {
  private final int value;
  private final CardType type;
  private final Color color;

  //I'll omit the constructor, getters, equals and hashcode for simplicity, they should be straight forward
}

建造甲板:

List<Card> deck = new ArrayList<>(208); //we're telling the list that we expect 208 elements

//build two cards for each combination and add them to the deck
for( int value = 1; value  <= 14; value++ ) {
  for( CardType type : CardType.values() ) {
    for( Color color : Color.values() ) {
      deck.add( new Card( value, type, color ) );
      deck.add( new Card( value, type, color ) );
    }
  }
}

//shuffle the deck
Collections.shuffle( deck );

1
当您使用不可变的Card实例时,无需两次执行new Card(value,type,color),只需将相同的实例添加到列表中两次即可。甚至可以进一步进行优化,当您始终仅创建每种Card的单个实例时,它的工作方式类似于enum,因此您无需覆盖equalshashCode - Holger
@Holger 你说得对,我们可以这样做。但我还是会保持现状,因为否则可能会对 OP(显然在 equalshashCode 上遇到问题)变得有点太复杂了。而且在某个时候,他可能想要向单个卡实例添加其他数据(例如一些唯一的 ID 来检查它们是否被“重复”/同时由两个玩家持有 :)),因此拥有 2 个实例更接近于模拟真实世界。 - Thomas
@Thomas 非常感谢!!它解决了我的问题,现在我将看看如何正确添加等于和哈希码。 - OthK

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接