Доступ к полям класса из индекса arrayList? - PullRequest
0 голосов
/ 27 января 2020

Мне нужно получить доступ ко множеству очень похожих объектов и ко всему внутри них. Пока у меня есть три класса:

"Piece" - пока ничего не делает, но имеет подкласс LcPawn.

"LcPawn" - Это одна строка кода, '' 'publi c stati c int ID; '' ', который должен содержать разные номера для каждого экземпляра LcPawn.

"Main" - рассматриваемый код выглядит следующим образом:

public static ArrayList<LcPawn> LcPawns = new ArrayList<LcPawn>(256);
for (int i = 0; i < 256; i ++) {
    LcPawns.add(i, new LcPawn());
}
for (int i = 0; i < LcPawns.size(); i ++) {
    LcPawns.get(i).ID = i; 
}
for (int i = 0; i < LcPawns.size(); i ++) {
    System.out.println(LcPawns.get(i).ID);
}

Однако на консоли ничего не появляется. Отдельные циклы, так что я могу убедиться, что это работает без необходимости сбрасывать все объекты снова и снова. Это столько, сколько я знаю.

1 Ответ

1 голос
/ 27 января 2020

Обратите внимание:

Ваш класс LcPawn содержит переменную public static int ID;, которая, как вы говорите, должна иметь разные значения для каждого экземпляра. В Java ключевое слово static в этом контексте делает противоположное тому, что оно объявляет «переменную класса» вместо «переменной экземпляра». Чтобы обеспечить один экземпляр ID для каждого экземпляра LcPawn, просто удалите static здесь, и это должно быть хорошо.

Во-вторых, следует придерживаться соглашения, согласно которому все поля private должны быть сделаны, при обеспечении "добытчиков и сеттеров". Например, вместо того, чтобы объявить класс следующим образом:

public class MyClass {
    public int value;
}

вместо этого объявите его как:

public class MyClass {
    private int value;

    public void setValue(int value) {
        this.value = value;
    }

    public int getValue() {
        return this.value;
    }
}

Это имеет несколько преимуществ:

  • Вы можете добавить бизнес-логику c к функциям, например, возможно, вы хотите запретить отрицательные числа в поле value. Вы можете добавить строку: if (value < 0) throw new NegativeNumberException();

  • Вы можете изменить реализацию без изменения остальной части вашего кода. Возможно, вы хотите получить свое значение из inte rnet, или вы используете библиотеку, которая хочет лениво загрузить вашу переменную. Это возможно только при вызове метода и не может быть сделано необработанной переменной.

  • Многие популярные библиотеки ожидают, что классы будут в этом формате (например, Jackson Databind и Spring).

Вы также должны соблюдать стандартные Java правила использования заглавных букв:

  • имена полей и методы пишутся likeThis и likeThis()
  • имена классов написаны LikeThis
  • константы написаны LIKE_THIS

Имея это в виду, вот как я бы написал ваш код:

public static void main(String[] args) {
    List<LcPawn> pawns = new ArrayList<>(256);  // more generic type and type parameter omitted for brevity

    for (int i = 0; i < 256; i++) {
        pawns.add(new LcPawn());  // no need to specify an index, it gets added to the end by default
    }

    for (int i = 0; i < pawns.size(); i++) {
        pawns.get(i).setId(i);  // using setter method
    }

    for (int i = 0; i < pawns.size(); i++) {
        System.out.println(pawns.get(i).getId());  // using getter method
    }
}

Однако это может быть сжато в один for l oop:

List<LcPawn> pawns = new ArrayList<>(256);
for (int i = 0; i < 256; i++) {
    LcPawn pawn = new LcPawn();
    pawn.setId(i);
    System.out.println(pawn.getId());
    pawns.add(pawn);
}

Или с Java 8 потоками:

IntStream.range(0, 256)  // generate a stream of integers from 0-255
    .map(i -> {  // map each integer to a pawn with that integer as its id
        LcPawn pawn = new LcPawn();
        pawn.setId(i);
        return pawn;
    })
    .forEach(System.out::println);  // print all of them, using a "method reference"
...