0

I'm building a class that manage Vector<Studente> and Vector<StudenteLaureato> types, where StudenteLaureato extends Studente. Before I added the method inserisciLaureati which merges Vector<Studente> and Vector<StudenteLaureato>, everything was working fine. Now, when I passstampaDati a Vector<Studente> that also contains StudenteLaureatoobjects, it doesn't print their subclass specific attributes. Can't figure out how to edit the function to solve this.

public class GestioneRegistro {
    private Vector<Studente> elenco = new Vector<Studente>();

    Vector<Studente> letturaDati(String nomeFileDaLeggere) {
    System.out.println("inizio la lettura");
    String rowRead;
    BufferedReader in;
    in = new BufferedReader(new InputStreamReader(new FileInputStream(nomeFileDaLeggere)));
        while((rowRead = in.readLine()) != null) {
            StringTokenizer st = new StringTokenizer(rowRead);
            StudenteLaureato s = new StudenteLaureato(st.nextToken(), st.nextToken(), st.nextToken());
            elenco.add(s);
        }
    return elenco;
    }

    public void stampaDati(Vector<Studente> elencoloc){
        List<Studente> arrlist = new ArrayList<Studente>();
        Enumeration<Studente> e = elencoloc.elements(); 
        arrlist = Collections.list(e);
        System.out.println("Contenuto di elenco: "+arrlist);
    }

    public Vector<Studente> merger(Vector<Studente> Va, Vector<Studente> Vb) {
          Vector<Studente> merge = new Vector<Studente>();
          merge.addAll(Va);
          merge.addAll(Vb);
          return merge;
        }
    public void inserisciLaureati(Vector<Studente> elencoloc, String nomeFileDaLeggere) {
        elencoloc = merger( elencoloc, letturaDati(nomeFileDaLeggere));
    }

    public static void main(String args[]) {
    GestioneRegistro reg = new GestioneRegistro();
    Vector<Studente> elencoloc = new Vector<Studente>();
    elencoloc = reg.letturaDati(args[0]);
    reg.stampaDati(elencoloc);
    reg.inserisciLaureati(elencoloc, "C:\\Users\\Nixon\\Desktop\\archiviolau.txt");
}
}

where Studente is this:

public class Studente implements Serializable{
    private static final long serialVersionUID = 1L;

    String nome;
    String cognome;
    String matricola;

    public Studente(String n, String c, String m){
        nome = n;
        cognome = c;
        matricola = m;
    }
    public String toString() {
        return nome+" "+cognome+" "+matricola;
    }
}

and StudenteLaureato is this:

public class StudenteLaureato extends Studente {
    private static final long serialVersionUID = 1L;

    String indirizzo;
    String dataLaurea;
    public StudenteLaureato(String n, String c, String m, String i, String d) {
        super(n, c, m);
        indirizzo = i;
        dataLaurea = d;
    }
    public StudenteLaureato(String n, String c, String m){
        super(n, c, m);
    }
    public String toString() {
        return nome+" "+cognome+" "+matricola+" "+indirizzo+" "+dataLaurea;
    }
}
Nicola Amadio
  • 149
  • 2
  • 11
  • Did I get that right? You have a list of Animals, and a list of Dogs, and you want that to merge into a list of Dogs? Sure about that? If so - how do you think that is supposed to work? (every Dog is an Animal, but not all Animals are Dogs)?! – GhostCat Jan 17 '18 at 15:48
  • I want a list with both dogs and animals. – Nicola Amadio Jan 17 '18 at 15:53
  • 1
    Then you need a list of Animals. It is that simple. Because the ONLY common thing is - both types of objects that can be in a list are Animals. Like least common denominator. – GhostCat Jan 17 '18 at 15:59
  • @Nix__On You can only have a list of animals `List` which can contain dogs, but you can't tell anymore what kind of animal it is, or a List which cannot contain other kinds of animals. If you have a `List`, you can call methods of the `Animal` interface and they will resolve the type dynamically. – Jens Jan 17 '18 at 16:00
  • This is the situation that I had at the beginning. But then, when I was using a method to print the list out, it would just print animal's attributes, even if they were dogs. – Nicola Amadio Jan 17 '18 at 16:07
  • 1
    @Nix__On You need to override the methods in `Dog` which should behave differently for dogs. Otherwise, the compiler cannot know that Dogs should behave differently than their base-class and just calls the base-class methods. – Jens Jan 17 '18 at 16:15
  • I did override the toString in dog. – Nicola Amadio Jan 17 '18 at 16:17
  • 1
    Ok, I don't think this will get any further without an example of the problem. Please show executable, real code and what you are seeing and what you expect. If you override `toString()` correctly it will work. – Jens Jan 17 '18 at 16:19
  • I will edit the whole question. Thank you for keep trying, I hope we'll get this done. – Nicola Amadio Jan 17 '18 at 16:23
  • I edited the whole question, hope it's easy to understand now. – Nicola Amadio Jan 17 '18 at 16:52
  • @Nix__On I've modified the example a little bit to create a runnable example. You can find and execute it here: https://ideone.com/02tkVi. It behaves as expected and call the correct `toString` methods. Can you change your example such that it can be copied&pasted into an ide and reproduces the error? – Jens Jan 17 '18 at 19:24

1 Answers1

0

You have to tell the compiler that youre merge method accepts vectors of ClassA and all sub-classes. This is called covariance and in Java you use the wildcard ? for that:

class A {}
class B extends A {}
class C extends A {}

public void foo(List<A> as, List<B> bs, List<C> cs) {
    merge(as,as);
    merge(bs,bs);
    merge(cs,cs);
    merge(bs,as);
    merge(cs,as);
    merge(bs,cs);
}

public <T> List<T> merge(List<? extends T> x, List<? extends T> y) {
    List<T> result = new ArrayList<T>();
    result.addAll(x);
    result.addAll(y);

    return result;
}

Now, the compiler infers the type T as the parent type of the elements of x and y.

There is a very good explanation of wildcard types and their usage as parameters in Effective Java. I would definitely recommend to read this.

You can also encode this directly as constraints for type variables. However, since we are not interested in the types X and Y except that they are some sub-class of T, I would prefer the wildcard.

public <T, X extends T, Y extends T> List<T> merge(List<X> x, List<Y> y) {
    List<T> result = new ArrayList<T>();
    result.addAll(x);
    result.addAll(y);

    return result;
}

It also recommended to not use the old collection classes such as Vector.

Jens
  • 9,058
  • 2
  • 26
  • 43
  • @Nix__On It is good custom to post a complete minimal example (https://stackoverflow.com/help/mcve). This would help others to understand your problem better and point out where the problem is. Very helpfull would be compilable code and an error message form the compiler. – Jens Jan 17 '18 at 15:06
  • you're right. I was having trouble to add code in the comment. I know updated my question with the error message and the change I did. – Nicola Amadio Jan 17 '18 at 15:23
  • @Nix__On You need to add some code from the context. Try to create a small example in a single which contains everything needed to show the error. You can start by copying your code and remove anything that is not needed, e.g. member functions and variables, functioon bodies etc. The final code probably contains two classes with empty bodies (Studente and StudenteLaureate) and a couple of functions. – Jens Jan 17 '18 at 15:28
  • I added the other related parts. It looks very long but there are now all the things used when calling the merger. – Nicola Amadio Jan 17 '18 at 15:48
  • 1
    @Nix__On It is still not a minimal complete example. E.g. the bodies of Studente and StudenteLaureate are probably not needed, the details of parsing the file are probably irrelevant etc. Really, copy your code in a single file and strip out everything you can. Then, paste the contents of this file instead of snippets. – Jens Jan 17 '18 at 15:54
  • @Nix__On I also don't see a call to `merger` or `merge`. – Jens Jan 17 '18 at 16:07
  • it was in mergFunc. But, given the other comments, I think I will go back to the list of animals and try to formulate the problem I get while printing. – Nicola Amadio Jan 17 '18 at 16:10