2015-02-19 3 views
0

В следующем (неправильном) коде я хочу инициализировать объекты, содержащиеся в массиве cards, для создания колоды. Есть ли способ сделать это с помощью расширенного цикла или мне нужно использовать «стандартный» цикл?Возможно ли инициализировать объекты в массиве с помощью расширенного цикла?

cards = new Card[SUITS][RANKS]; 

for(Card[] suit : cards) { 
    for(Card card : suit) { 
     card = new Card(suitVar, rankVar); 
    } 
} 
+3

Знаете ли вы разницу между ['call on value' и' call by reference'] (http://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by -стоимость)? – Tom

ответ

2

Нет, это невозможно, потому что усиленный цикл for даст ссылку на текущий элемент. Присвоение нового объекта ссылке не присваивает элемент массиву. Невозможно использовать выражение доступа к массиву для назначения элемента массиву.

Вы можете использовать две «традиционные» петли 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(...), ... }, 
    ...}; 

Интересно, потому что 2D массив реализован как массив массивов, и используются ссылки на массив, то внешней массив может быть инициализирован с расширенной for петли, до тех пор, как внутренней массива инициализируется «традиционным» циклом. Это работает, потому что 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); 
    } 
} 
+0

Возможно, я слишком долго не был в Java-мире, но вам также не нужно было инициализировать каждую 'Card []' внутри массива 'cards'? – StriplingWarrior

+1

@StriplingWarrior Нет, 2D-массив создается правильно при инициализации. Каждый элемент имеет значение «null», которому требуется инициализация, но не субмассивы. – rgettman

+0

Nifty. Спасибо за ответ. – StriplingWarrior

0

Нет, вы не можете использовать Еогеасп.
Это главным образом потому, что для каждого доступно только чтение, но также и потому, что вы переписываете ссылку объекта в цикле. 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 

Нормальный путь заключается в использовании нормальный для цикла.

0

Для этого конкретного примера, хорошая стратегия будет заключаться в создании enum с для костюмов и рангов. Затем вы можете инициализировать колоду, перевернув ее.

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)); 
    } 
} 

Это позволяет использовать расширение for перебирает enum с, а не массив самой карты. Это также лучшее представление о системе, которую вы пытаетесь моделировать. Таким образом, он сильно зависит от конкретного случая, но это может быть применено не только к картам с костюмом и рангом. Соответственно ли это следует определять в каждом конкретном случае.

Чтобы ответить более непосредственно: не так, как вы это делаете, но с альтернативной (и в этом случае лучше) моделью становится возможной.

Смежные вопросы