是否可以通过增强的for循环来初始化数组中的对象?
Is it possible to initialize the objects in an array through an enhanced for loop?
在以下(错误的)代码中,我想初始化数组 cards
中包含的对象以创建一个牌组。有没有办法通过增强的 for 循环来做到这一点,或者我必须使用 "standard" for 循环?
cards = new Card[SUITS][RANKS];
for(Card[] suit : cards) {
for(Card card : suit) {
card = new Card(suitVar, rankVar);
}
}
不,你不能使用foreach。
这主要是因为 for each 是只读的,而且还因为您会在循环中覆盖对象的引用。 Java 这样不行。好吧,我不知道一种面向对象的语言可以在哪里工作。
你可以用这个简单的例子来测试它:
String[] strings = new String[10];
for(String s: strings)
s = "This won't work!";
for (String s : strings)
System.out.println(s);
它会打印出来
null
null
null
null
null
null
null
null
null
null
正常的方法是使用普通的 for 循环。
不,这是不可能的,因为增强的 for
循环将提供对当前元素的引用。将新对象分配给引用不会将元素分配给数组。使用数组访问表达式将元素分配给数组是无可替代的。
您可以使用两个 "traditional" for
循环和数组访问表达式来初始化数组。
for (int s = 0; s < SUITS; s++)
for (int c = 0; c < RANKS; c++)
cards[s][c] = new Card(...);
可以使用数组初始值设定项,但它会乏味、过于冗长且容易出错。
cards = new Card[][] {
{new Card(...), new Card(...), ... },
{new Card(...), new Card(...), ... },
...};
有趣的是,因为二维数组实现为数组的数组,并且使用了数组引用,所以outer数组可以用增强的for
循环初始化,只要 inner 数组用 "traditional" 循环初始化。这是有效的,因为 suit
是 cards
中的一个数组,所以 suit[c]
是 cards
.
中的一个元素
cards = new Card[SUITS][RANKS];
for(Card[] suit : cards) {
for(int c = 0; c < RANKS; c++) {
suit[c] = new Card(suitVar, rankVar);
}
}
对于这个特定示例,一个好的策略是为花色和等级创建 enum
s。然后你可以通过循环这些来初始化一个甲板。
public enum Suit { CLUB, DIAMOND, HEART, SPADE }
public enum Rank {
ACE,
TWO,
...
QUEEN,
KING
}
然后
List<Card> deck = new ArrayList(Suit.values().length * Rank.values.length);
for (Suit s: Suit.values()) {
for (Rank r: Rank.values()) {
deck.add(new Card(s, r));
}
}
这允许您在 enum
上使用增强的 for
循环,而不是卡片数组本身。它也是您尝试建模的系统的更好表示。因此,它在很大程度上取决于具体情况,但这不仅仅适用于具有花色和等级的牌。这是否合适应根据具体情况确定。
所以更直接地回答:不是你这样做的方式,而是使用替代模型(在这种情况下,更好),这成为可能。
在以下(错误的)代码中,我想初始化数组 cards
中包含的对象以创建一个牌组。有没有办法通过增强的 for 循环来做到这一点,或者我必须使用 "standard" for 循环?
cards = new Card[SUITS][RANKS];
for(Card[] suit : cards) {
for(Card card : suit) {
card = new Card(suitVar, rankVar);
}
}
不,你不能使用foreach。
这主要是因为 for each 是只读的,而且还因为您会在循环中覆盖对象的引用。 Java 这样不行。好吧,我不知道一种面向对象的语言可以在哪里工作。
你可以用这个简单的例子来测试它:
String[] strings = new String[10];
for(String s: strings)
s = "This won't work!";
for (String s : strings)
System.out.println(s);
它会打印出来
null
null
null
null
null
null
null
null
null
null
正常的方法是使用普通的 for 循环。
不,这是不可能的,因为增强的 for
循环将提供对当前元素的引用。将新对象分配给引用不会将元素分配给数组。使用数组访问表达式将元素分配给数组是无可替代的。
您可以使用两个 "traditional" for
循环和数组访问表达式来初始化数组。
for (int s = 0; s < SUITS; s++)
for (int c = 0; c < RANKS; c++)
cards[s][c] = new Card(...);
可以使用数组初始值设定项,但它会乏味、过于冗长且容易出错。
cards = new Card[][] {
{new Card(...), new Card(...), ... },
{new Card(...), new Card(...), ... },
...};
有趣的是,因为二维数组实现为数组的数组,并且使用了数组引用,所以outer数组可以用增强的for
循环初始化,只要 inner 数组用 "traditional" 循环初始化。这是有效的,因为 suit
是 cards
中的一个数组,所以 suit[c]
是 cards
.
cards = new Card[SUITS][RANKS];
for(Card[] suit : cards) {
for(int c = 0; c < RANKS; c++) {
suit[c] = new Card(suitVar, rankVar);
}
}
对于这个特定示例,一个好的策略是为花色和等级创建 enum
s。然后你可以通过循环这些来初始化一个甲板。
public enum Suit { CLUB, DIAMOND, HEART, SPADE }
public enum Rank {
ACE,
TWO,
...
QUEEN,
KING
}
然后
List<Card> deck = new ArrayList(Suit.values().length * Rank.values.length);
for (Suit s: Suit.values()) {
for (Rank r: Rank.values()) {
deck.add(new Card(s, r));
}
}
这允许您在 enum
上使用增强的 for
循环,而不是卡片数组本身。它也是您尝试建模的系统的更好表示。因此,它在很大程度上取决于具体情况,但这不仅仅适用于具有花色和等级的牌。这是否合适应根据具体情况确定。
所以更直接地回答:不是你这样做的方式,而是使用替代模型(在这种情况下,更好),这成为可能。