Joseph Maan Anayee Joseph Maan Anayee - 2 months ago 7
Java Question

Generics and ArrayList

How can I access the methods in the Students class. When I print myList it uses the toString in the students class, I'm not sure how to access the other methods. Is that even possible?

PS I already have the try and catch in my program, I just didn't post here to make the code shorter.

public class DatabaseAccess <T> {
public T[] database;
public ArrayList<T>myList = new ArrayList<T>();
public ArrayList<T> testlist = new ArrayList<T>();
public void userInterface(){
int count = 1;
for (T i : myList){
System.out.println(count++ + ": " + i);
}
}
public void readDatabase(){
try {
ObjectInputStream in = new ObjectInputStream(new FileInputStream("grocery.bin"));
database = (T[]) in.readObject();
for (int i = 0; i < database.length; i++){
myList.add(database[i]);
}
myList.add((T) "\n");
myList.add((T) "\tStudents:");
ObjectInputStream in1 = new ObjectInputStream(new FileInputStream("students.bin"));
database = (T[]) in1.readObject();
for (int i = 0; i < database.length; i++){
myList.add(database[i]);
}
}
}



public class Student implements Serializable, Comparable{
private String name, id, address;
private double gpa;

public Student(String name, String id, double gpa){
this.name = name;
this.id = id;
this.gpa = gpa;
}
public int compareTo(Object object){
Student student = (Student ) object;
if(this.gpa < student.getGpa())
return -1;
else
if(this.gpa > student.getGpa())
return 1;
else
return 0;
}
public String getName(){ return name;}
public String getId(){ return id;}
public double getGpa(){ return gpa;}
public String toString(){ return (String.format("%16s%10.4s%8s", name, id, gpa));}
}

Answer

Assuming you mean within DatabaseAccess, in theory, you don't.

Now, you COULD use something like the following, but it is a horrible idea and absolutely reeks of bad design (no offense meant - I just don't want to give the impression that this code is at all okay or that you should use it - just that it is technically possible):

 for (T t : myList) {
    if (t instanceof Student) {
      Student student = (Student) t;
      student.getGpa();
    } else if (t instanceof Food) {
      ...
    }
 }

As far as DatabaseAccess is concerned, it's not a Student. It's a random object of type T which we know basically nothing about. If you can't create a common interface between the Student and Food to do what you want, you have to ask yourself why this DatabaseAccess needs to know the specifics of the classes and figure out what the design should really look like to separate things more sanely.

Are you doing some custom printing? Maybe the formatting should be done within the Student/Food class.

Are you, e.g. processing user input and manipulating data from the objects in the database? Separate the concerns of database access and data manipulation. Changing a GPA shouldn't necessarily require you to know whether the data is being stored in an ObjectOutputStream or an Oracle Database. So, have the DatabaseAccess deal with the database, and define some other class that works with a DatabaseAccess<Student> through some defined interface, and have that handle the Student-specific manipulation.

Without knowing precisely what you're trying to do, it's hard to give solid advice beyond: if you think you need to do what you're asking, you might want to step back and think if there might be a better way to approach the problem so that you don't.