Як ініціалізувати масив об’єктів у Java


79

Я хочу ініціалізувати масив об'єктів Player для гри BlackJack. Я багато читав про різні способи ініціалізації примітивних об'єктів, таких як масив ints або масив рядків, але я не можу перенести концепцію на те, що я намагаюся зробити тут (див. Нижче). Я хотів би повернути масив ініціалізованих об'єктів Player. Кількість об'єктів програвача для створення - це ціле число, для якого я пропоную користувачеві. Я думав, що конструктор може прийняти цілочисельне значення і відповідно назвати програвач, ініціалізуючи деякі змінні-елементи об'єкта Player. Я думаю, що я близький, але все ще досить розгублений.

static class Player
{
    private String Name;
    private int handValue;
    private boolean BlackJack;
    private TheCard[] Hand;

    public Player(int i)
    {
        if (i == 0)
        {
            this.Name = "Dealer"; 
        }
        else
        {
            this.Name = "Player_" + String.valueOf(i);
        }
        this.handValue = 0;
        this.BlackJack = false;
        this.Hand = new TheCard[2];
    } 
}
private static Player[] InitializePlayers(int PlayerCount)
{ //The line below never completes after applying the suggested change
    Player[PlayerCount] thePlayers;
    for(int i = 0; i < PlayerCount + 1; i++)
    {
        thePlayers[i] = new Player(i);
    }
    return thePlayers;
}

EDIT - UPDATE: Ось що я отримую після зміни цього, як я зрозумів вашу пропозицію:

Thread [main] (Suspended)   
    ClassNotFoundException(Throwable).<init>(String, Throwable) line: 217   
    ClassNotFoundException(Exception).<init>(String, Throwable) line: not available 
    ClassNotFoundException.<init>(String) line: not available   
    URLClassLoader$1.run() line: not available  
    AccessController.doPrivileged(PrivilegedExceptionAction<T>, AccessControlContext) line: not available [native method]   
    Launcher$ExtClassLoader(URLClassLoader).findClass(String) line: not available   
    Launcher$ExtClassLoader.findClass(String) line: not available   
    Launcher$ExtClassLoader(ClassLoader).loadClass(String, boolean) line: not available 
    Launcher$AppClassLoader(ClassLoader).loadClass(String, boolean) line: not available 
    Launcher$AppClassLoader.loadClass(String, boolean) line: not available  
    Launcher$AppClassLoader(ClassLoader).loadClass(String) line: not available  
    BlackJackCardGame.InitializePlayers(int) line: 30   
    BlackJackCardGame.main(String[]) line: 249  

чи є причина, чому Playerклас сироватки є статичним? Ви можете спробувати видалити staticз нього ключове слово?

Добре - я спробував видалити "static", і компілятор позначив таке: thePlayers [i] = new Player (i);
Джон Адамс,

Щось на зразок цього pastie.org/1865618 має скомпілювати.
Bala R

Відповіді:


98

Це майже нормально. Просто майте:

Player[] thePlayers = new Player[playerCount + 1];

І нехай цикл буде:

for(int i = 0; i < thePlayers.length; i++)

І зауважте, що конвенція Java диктує, що імена методів та змінних повинні починатися з малих літер.

Оновлення: розмістіть свій метод у тілі класу.


1
Не знаю, що ви маєте на увазі тут. У мене є конструктор всередині класу Player. Ви маєте на увазі помістити InitializePlayers всередину класу Player?
Джон Адамс,

1
@ Джон Гальт так. Це не може бути поза класом
Божо

@Powerlord Незважаючи на те, що він може містити широко використовувані конвенції та давати добрі пропозиції, я майже впевнений, що половина елементів у цьому документі занадто незрозуміла, щоб насправді вважатися ними.
твіз

@twiz Щоб бути справедливим, цей документ є умовами програмування. Oracle, яка народилася Sun, має власних розробників. Я не переглядав код до OpenJDK, щоб побачити, наскільки добре за ними стежили.
Powerlord

1
@Powerlord Code Conventions для мови програмування Java - це новий (старий) дім.

23

Замість

Player[PlayerCount] thePlayers;

ти хочеш

Player[] thePlayers = new Player[PlayerCount];

і

for(int i = 0; i < PlayerCount ; i++)
{
    thePlayers[i] = new Player(i);
}
return thePlayers;

повинен повернути масив, ініціалізований екземплярами програвача.

РЕДАГУВАТИ:

Перегляньте цю таблицю у wikipedia про загальноприйняті імена для Java.


Чи не буде це створювати витоки пам'яті, коли ваша повторна ініціалізація масиву thePlayers є циклом?

14

Якщо ви не впевнені в розмірі масиву або якщо він може змінитися, ви можете зробити це, щоб мати статичний масив.

ArrayList<Player> thePlayersList = new ArrayList<Player>(); 

thePlayersList.add(new Player(1));
thePlayersList.add(new Player(2));
.
.
//Some code here that changes the number of players e.g

Players[] thePlayers = thePlayersList.toArray();

1
Я віддав би перевагуList<Player> thePlayersList = new ArrayList<Player>();
Deqing

2
@Deqing У такому випадку я віддав би перевагу Object thePlayersList = new ArrayList<Player>();.
Джоель Сьогрен,

@Deqing Це насправді працюватиме по-іншому у випадку перевантаження.
Ніл

9

Якщо ви можете жорстко ввести кількість гравців

Player[] thePlayers = {
    new Player(0),
    new Player(1),
    new Player(2),
    new Player(3)
};

1

Після ініціалізації масиви не змінюються. Ви повинні дати йому значення, і саме це значення залишається довжиною масиву. Ви можете створити кілька масивів, щоб містити певні частини інформації про гравця, такі як їхні руки та подібні, а потім створити arrayList, щоб сортувати ці масиви.

Ще однією точкою суперечок, яку я бачу, і я можу помилитися з цього приводу, є той факт, що ваш приватний Player [] InitializePlayers () є статичним там, де клас зараз не статичний. Так:

private Player[] InitializePlayers(int playerCount)
{
 ...
}

Моїм останнім зауваженням було б те, що вам, мабуть, слід оголосити playerCount поза методом, який збирається його змінити, щоб значення, яке йому встановлено, також стало новим значенням, і воно не просто викидалося в кінці методу "сфера застосування".

Сподіваюся, це допомагає


1
Player[] players = Stream.iterate(0, x-> x+1 ).limit(PlayerCount).map(i -> new Player(i)).toArray(Player[]::new);

0

thePlayers[i] = new Player(i); Я просто видалив iвсередині Player(i); і це спрацювало.

тому рядок коду повинен бути:

thePlayers[i] = new Player9();

Я думаю, це тому, що спосіб, яким він визначив гравця, public Player(int i)Отже, спочатку він повинен приймати ціле число.
dexhunter
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.