Добавление нового члена класса в ArrayList, автоматическое увеличение идентификатора

Контекст У меня простой класс учащихся (при необходимости см. в конце). В другом классе я хочу заполнить массив учеников, и пользователь может добавить своего ученика. Студенты помечены как s01, s02 и т. д., и я хотел бы, чтобы программа автоматически присваивала следующий идентификатор новому студенту.

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

public static List<Student> populate(){
        //skipped a few lines of student creation

        List<Student> students = new ArrayList<Student>();
        students.add(s01);
        students.add(s02);

        //The list now contains the 2 students
        //Now I want to add a student myself
        System.out.println("Enter a name: ");
        String NewName = reader.next();

        //I want the program to recognize that there are 2 students in the arrayList and 
        //Automatically make next Student s03. 
        //I can figure out how to determine it is the 3 that is needed
        //But I don't think the identifier can be a string. I tried this: 

        String nextStudent = "s03"
        Student nextStudent = new Student(NewName);
        //          ^How can I set this to be a variable?
        students.add(nextStudent);
        return students;
    }

Мой студенческий класс

public class Student {

    String name;
    int age;
    String program;

    public Student(String StudentName){
        this.name = StudentName;
    }

    public void PrintInfo(){
        System.out.println(name + " is a " + age +" year old student in " + program);
    }

    public static void main(String[] args) {
    }

}

person David G    schedule 11.03.2016    source источник
comment
Также я использую термин «идентификатор», но я относительно уверен, что это неправильный термин. Если бы кто-нибудь подсказал мне, как это называется, было бы здорово!   -  person David G    schedule 11.03.2016
comment
Я действительно не понимаю вашей проблемы, почему бы просто не использовать то, что у вас есть: Student nextStudent = new Student(NewName); ?   -  person Idos    schedule 11.03.2016
comment
Потому что я хотел бы, чтобы это было в цикле, где пользователь может добавить столько студентов, сколько захочет. И так должно пройти s01, s02, s03, s04 само собой. Вот почему я хотел сделать это переменной, которая может увеличиваться.   -  person David G    schedule 11.03.2016
comment
@DavidG Вы не можете устанавливать имена переменных во время выполнения. Если вы хотите пройти через ArrayList, используйте: for (Student s : students){ // do something }   -  person rj93    schedule 11.03.2016
comment
Хорошо, я был под впечатлением, что это было необходимостью. Спасибо   -  person David G    schedule 11.03.2016


Ответы (5)


Student nextStudent = new Student(NewName);
            ^How can I set this to be a variable?

Это невозможно. Но вам не нужно: просто удалите String nextStudent = "s03". Нет необходимости в том, чтобы переменная называлась s03: при условии, что имена переменных уникальны, фактическое имя переменной не оказывает семантического влияния на программу.

person Andy Turner    schedule 11.03.2016
comment
Потому что я хотел бы, чтобы это было в цикле, где пользователь может добавить столько студентов, сколько захочет. И так должно пройти s01, s02, s03, s04 само собой. Вот почему я хотел сделать это переменной, которая может увеличиваться. - person David G; 11.03.2016
comment
Но вам не нужно, чтобы имя переменной было чем-то конкретным. Просто создайте экземпляр в цикле и добавьте его в список. Вы просто не можете иметь динамические имена переменных в Java. - person Andy Turner; 11.03.2016
comment
Ok. Мне удалось зациклить студентов и полностью отказаться от идентификаторов s0x. Теперь я создаю учеников, добавляя их в цикл с помощью students.add(new Student(NewName));, где NewName — строка ввода пользователя. Однако при этом, как я могу установить возраст и программу? Обычно я писал бы s01.age = 3, но теперь я вообще не ставил s01. Вы поняли мой вопрос или мне задать новый? - person David G; 11.03.2016
comment
Я больше не использую nextStudent, я создаю студентов, используя строку, которую я написал в комментарии выше. При этом как я впоследствии буду обращаться к своим ученикам? Я вижу вашу правку. Поскольку он находится в цикле, я не могу использовать Student nextStudent = new Student(NewName);, потому что не может быть нескольких названий nextStudent (или я ошибаюсь?) - person David G; 11.03.2016
comment
Ты неправ. Каждый раз в цикле nextStudent ссылается на новый экземпляр, потому что он объявлен как Student nextStudent = new Student(...); - person Andy Turner; 11.03.2016
comment
Неважно, это работает. Думаю, я не так хорошо понимаю объектно-ориентированный подход, как я. - person David G; 11.03.2016

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

for (Student stud : students){
    // do stuff with each student here
}

Или альтернативно:

for (int i = 0; i < students.size(); i++){    
    students.get(i) // now you can do whatever you want with the i'th student
}
person Idos    schedule 11.03.2016

Если вы хотите автоматически назвать свой новый Student в зависимости от размера вашего List, вы можете использовать следующую идиому:

students.add(new Student(String.format("s0%d", students.size() + 1)));

Приведенный выше код выполняет следующие встроенные операции:

  • Форматирует String с "s0" плюс размер вашего students" list+ 1`
  • Передает этот String (например, "s03") конструктору Student
  • Создает новый Student, используя конструктор, параметризованный этим String
  • Добавляет новый Student к вашему List

Это должно заменить ваш код здесь, который не будет компилироваться:

String nextStudent = "s03"
Student nextStudent = new Student(NewName);

Примечание

Идиома String.format форматирует String C-стиль, основанный на предполагаемых типах данных и аргументах.

Начало String является константой ("s0") и не «выживет» при размере списка учащихся, превышающем 9 (крайний случай для вас).

Формат "%d" указывает целое число, значение которого задается students.size() + 1.

Также обратите внимание

Имена переменных camelBack, а не CamelCase (что, в свою очередь, зарезервировано для имен классов, интерфейсов и перечислений).

person Mena    schedule 11.03.2016

Похоже, вы хотите, чтобы ваши ученики были s01, s02, s03, s04 и так далее. Итак, что вы можете сделать, так это сохранить целочисленную статическую переменную внутри вашего класса Student, чтобы подсчитывать, сколько объектов вы создали до сих пор, и дать им соответствующее имя, например:

public class Student {

    private static int counter = 0;

    String id;
    String name;
    int age;
    String program;

    public Student(String name, int age, String program) {
        //pass relevant info in the constructor
        this.name = name;
        this.age = age;
        this.program = program;
        this.id = String.format("%02d", ++counter);
    }

    // rest of your methods
}

И затем каждый раз, когда вы добавляете Student к вашему ArrayList, ему автоматически будет присвоен последующий «идентификатор»:

public static List<Student> populate(){

    List<Student> students = new ArrayList<Student>();
    students.add(new Student(/*student parameters*/));
    students.add(new Student(/*student parameters*/));

    System.out.println("Enter a name: ");
    String newName = reader.next();
    //do the same with age and program

    Student nextStudent = new Student(newName, newAge, newProgram);
    students.add(nextStudent);
    return students;
}

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

person Ori Lentz    schedule 11.03.2016

Вероятно, вам нужна карта для хранения ваших учеников с такими заданиями, как: s01, s02 и так далее...

Map<String, Integer> students = new HashMap<>();
//...
String nextStudent = "s" + Integer.toString(students.size());
students.put(nextStudent, new Student(NewName));
person Kamil    schedule 11.03.2016