Home > Enterprise >  List<String> issue
List<String> issue

Time:02-01

I have a problem with my small project.

I'm trying to add multiple subjects for all students, but I have no idea how to use List in my main ArrayList of all students. I have tried to use multiple ArrayList, but the code becomes too complicated.

/* Main class: */

class Student {
  private int id;
  private String name;
  private List<String> subjects;
  
  public Student(int id, String name, List<String> subjects) {
    this.id = id;
    this.name = name;
    this.subjects = subjects;
  }

  public String name() {
    return name;
  }

  public void setName(String name) {
    name = name;
  }

  public List<String> getSubjects() {
    Return subjects;
  }

  Public void addSubject(String subject) {
    Subjects.add(subject);
  }
}

Tester class:

class Tester {
  public static void main(String[] args) {
    List<Student> schoolStudents = new ArrayList(5);

    Student st1 = new Student (1, “John Smith”, “Maths”, “English);
    Student st2 = new Student (2, “Alan Smith”, “Physics”, “English);
    Student st3 = new Student (3, “John Jackson”, “History”, “English);
    Student st4 = new Student (4, “John Saxton”, “Maths”, “Physics);
    Student st5 = new Student (5, “Adam Smith”, “Maths”, “English);
}

Error code for ArrayList:

java.lang.string cannot be converted to java.util.list

CodePudding user response:

The constructor in your Student class defines 3 parameters. ID, Name and a List of Subjects yet you attempt to call the constructor with multiple subjects separated by a comma which is not at all possible. However we can leverage the power of varargs to achieve your particular use-case.

public class Student
{
  private int id;
  private String name;
  private List<String> subjects;

  public Student( int id, String name, String... subjects )
  {
    this.id = id;
    this.name = name;
    this.subjects = Arrays.asList(subjects);
  }
  // Omitted getters/setters
}

In this example the last parameter of the constructor is such a vararg. It allows you to add as many Strings as you like which is then converted to a list.

If changing the signature of the Student class is not an option you can achieve a similar behavior by converting the subjects to a list when creating the objects like this: Student st1 = new Student (1, "John Smith", Arrays.asList( "Math", "English"));

CodePudding user response:

For the most part, your class definition is fine. I would recommend using List.of to supply the list of subjects with a minor change in your constructor with some other things I point out at the end.

  • adding lists like this is straight forward.
  • and you need to copy the supplied list to an new ArrayList anyway to avoid shared objects.

You would call it like this.

Student student = new Student(1, "Maria", List.of("English", "Algebra"));

Look at the modified constructor in your class to see how the list is copied. The reasons are:

  • List.of is immutable and you want to be able to add subjects.
  • You could also use an existing list of subjects but then if that list is altered, so is your list in the Student instance.

class Student {
  private int id;
  private String name;
  private List<String> subjects;
  
  public Student(int id, String name, List<String> subjects) {
    this.subjects = new ArrayList<>(subjects);
    this.id = id;
    this.name = name;
    this.subjects = subjects;
  }

  public String name() {
    return name;
  }

  public void setName(String name) {
    name = name;
  }

  public List<String> getSubjects() {
    Return subjects;
  }

  Public void addSubject(String subject) {
    Subjects.add(subject);
  }
}

A few final observations.

  • In your addSubject method you need to change Subjects to subjects to match your field name.
  • In your getSubjects method, you should use return and make a defensive copy when you return the list.
    return new ArrayList<>(subjects);

This is good technique so that someone can't change the original list in your Student instance.

  • Lists grow dynamically. ArrayLists are backed by an array and start out with a default size. So you don't need to specify your list with a size. Just do the following and make certain you specify the <> since it is a generic class.
    List<Student> schoolStudents = new ArrayList<>();

CodePudding user response:

The last parameter of your constructor should be a ArrayList of Strings, which does not seem to be a good choice. But you are passing a single String in your Tester class, see "English" or "Physics".

Change your List<String> subjects to String subjects

  •  Tags:  
  • Related