构建一副牌的最有效方法(ArrayLists,Arrays等)?

时间:2016-09-09 20:26:48

标签: java arrays arraylist

所以我是Java的新手,并且在数组之前开始使用ArrayLists。 我喜欢它们与Python列表更相似,并且理解ArrayLists只包含对象而不是基元,在我看来,它们对包含多个类型的列表更有用。 我写这篇文章是为了展示我如何制作一副纸牌(这个例子的一切都是静态的):

public class Deck {

    private static Scanner input = new Scanner(System.in);
    private static Random newRan = new Random();

    private static final List RANKS = new ArrayList(Arrays.asList("ace", 2, 3, 4, 5, 6, 7, 8, 9,
            10, "jack", "queen", "king"));
    private static final List SUITS = new ArrayList(Arrays.asList("hearts", "diamonds", "clubs",
            "spades"));

    private static List makeDeck() {
        List result = new ArrayList();
        for (Object i : SUITS) {
            for (Object j : RANKS) {
                result.add(Arrays.asList(i, j));
            }
        }
        return result;
    }

    public static void main(String[] args) {
        List deck = makeDeck();

        for (Object i : deck) {
            System.out.println(i);
        }
    }
}

我认为这可能会减慢程序速度,正如我在别处读到的那样,但我想知道什么是更好,更传统或更干净的方法来实现这一目标? 所有建设性批评都受到欢迎。

(同样,我想说我写这个小代码只是为了演示我关于数组和数组列表及其功能的问题,这是一个简单的例子。)

4 个答案:

答案 0 :(得分:7)

Enums

Enums非常适合Card Suits和Ranks等。实际上,比字符串集更好。例如......

enum Suit {
    HEARTS, SPADES, DIAMONDS, CLUBS;
}

枚举也可以像任何其他类一样拥有自己的属性,但这是您可以单独阅读的内容。 Enums的高低是他们在运行时是单身人士,根据定义,每个人都是独一无二的。这些都是非常方便的属性。

接下来,我建议您实现正式的Card课程。卡不仅仅是一个属性列表。你想要这样的东西作为你的Card类的基础:

class Card {
   private final Suit suit;
   private final Rank rank;

   public Card(Suit suit, Rank rank) {
       this.suit = suit;
       this.rank = rank;
   }

   public Suit getSuit() { return this.suit; }

   public Rank getRank() { return this.rank; }
}

您的代码的用户会感谢您,而不是记住列表的第一个元素是套装还是卡的等级。

您必须重构makeDeck方法才能使用这些新的枚举和类,但一般方法将保持不变。迭代所有的Suits,并在该迭代中迭代所有等级并为每次迭代创建一个新的Card实例。这样,你就可以使用Rank和Suit的每个值制作一张新卡片。你最终得到一个完整的套牌。

现在,你要问自己的问题是:甲板只是卡片列表,还是属于自己的类?没有正确或错误的答案;这取决于你和你的程序需要什么。也许只使用一张名单就可以了。

哦,在那张纸条上(也许这只是一张图片),如果你想要一张“卡片列表”,可以把它作为卡片列表。 List<Card>优于List。通用类型是你的朋友!

答案 1 :(得分:0)

首先,删除这些行

private static Scanner input = new Scanner(System.in);
private static Random newRan = new Random();

因为它们不能在任何地方使用。

其次,使用更多面向对象的方法(标记它oop):

enum Suite {HEARTS, DIAMONDS, SPADES};
enum Value {ACE, TWO, THREE, FOUR, FIVE, SIX, TEN, JACK, QUEEN, KING};
class Card
{
    public Suite suite;
    public Value value;
    public Card (Suite s, Value v) {
        suite = s;
        value = v;
    }
    public String toString() {
        return s + " :: " + v;
}

泛型:

List - &gt; List<Card>
ArrayList - &gt; ArrayList<Card>

您的创建方法可以写成如下:

for (Suite s : Suite.values ())
    for (Value v : Value.values ())
        result.add (new Card (s, v));

此程序应如下所示:

import java.util.*;

public class Deck {
    public static enum Suite {
        DIAMONDS,
        SPADES,
        HEARTS
    }

    public static enum Value {
        ACE,
        TWO,
        THREE,
        FOUR,
        FIVE,
        SIX,
        TEN,
        JACK,
        QUEEN,
        KING
    }

    public static class Card {
        public Suite suite;
        public Value value;

        public Card (Suite s, Value v) {
            suite = s;
            value = v;
        }

        public String toString () {
            return String.format ("%s: %s", suite, value);
        }
    }

    private static List<Card> makeDeck() {
        List<Card> result = new ArrayList<>();
        for (Suite s : Suite.values ())
            for (Value v : Value.values ())
                result.add (new Card (s, v));
        return result;
    }

    public static void main(String[] args) {
        List<Card> deck = makeDeck();

        for (Card i : deck) {
                System.out.println(i);
        }
    }
}

答案 2 :(得分:0)

首先我要指出的是,数组并不仅限于保存原语。数组也可以容纳对象。例如..

vehicle[] cars = new vehicle[10];  // creates an array of 10 vehicle objects

现在已经没有了,数组和数组列表之间的主要区别在于数组的大小是固定的,而数组列表则不是。数组列表实际上只是核心的常规数组,但是当JVM注意到数组列表接近它的容量限制时,它只是在后台将数组内容复制到更大的数组。这样可以在使用数组列表时根据需要增大数组的大小。

这样做的副作用是在处理过程中会有一些额外的问题,但是如果要创建一个不够大的数组,则需要自己做很少的处理。这个处理几乎可以忽略不计,但是因为你的数组将是一个固定长度,所以数组列表不会为你做很多事情。

简而言之,如果您不确定阵列需要多少空间,那么阵列列表是最简单的方法。但是如果你的阵列长度固定(就像你的阵列一样),那么就可以使用简单的数组。数组就是你所需要的。希望它有所帮助!

答案 3 :(得分:0)

请注意,以下各项应位于不同的文件中:

public class Card {
    SUIT suit;
    RANK rank;
    public Card(SUIT suit, RANK rank) {
        this.suit = suit;
        this.rank = rank;
    }
}

public enum SUIT {
    Diamonds,
    etc
}

public enum RANK {
    Ace,
    Two,
    etc
}

public class Deck {
    ArrayList<Card> cards;

    public Deck() {
        cards = new ArrayList<Card>(RANK.values().length*SUIT.values().length); //for efficiency, specifies how big the arraylist should start as
        for(SUIT s : SUIT.values())
            for(RANK r : RANK.values())
                cards.add(new Card(s,r));
    }

    public static void main(String[] args) {
        Deck deck = new Deck(); //much cleaner code in main
    }
}