L m
L m

Reputation: 671

Java Generics : no suitable constructor found for ArrayList(List<CAP#1>)

So the questions needs me to design a method d to take in a list and a class and return it's contents back.

Write a class D that passes the following test.
jshell> class E { public String toString() { return "E"; }}
jshell> class F extends E { public String toString() { return "F"; }}
jshell> List<E> p = D.add(new ArrayList<E>(), new E())
jshell> List<F> q = D.add(new LinkedList<F>(), new F())
jshell> List<E> r = D.add(D.add(new LinkedList<E>(), new E()), new F())
jshell> List<F> s = D.add(D.add(new ArrayList<F>(), new F()), new F())
jshell> /var
| List<E> p = [E]
| List<F> q = [F]
| List<E> r = [E, F]
| List<F> s = [F, F]
jshell> List<E> x = D.join(p, q) // join q to the end of p
jshell> List<E> y = D.join(p, p)
jshell> List<F> z = D.join(q, q)
jshell> /var
| List<E> p = [E]
| List<F> q = [F]
| List<E> r = [E, F]
| List<F> s = [F, F]
| List<E> x = [E, F]
| List<E> y = [E]
| List<F> z = [F]

My current code looks like this

import java.util.List;
import java.util.ArrayList;

class D {

    public static <T> List <T> add(List<? super T> s,T t) {   
        s.add(t);
        return new ArrayList<T>(s);
    }
}

I keep gettinng this error : no suitable constructor found for ArrayList(List)

I'm supposed to input the toString value of this into the ArrayList however s.add(t.toString()); also gives an error

Upvotes: 0

Views: 720

Answers (1)

user
user

Reputation: 7604

A List<? super T> isn't a supertype of a List<T>. Even this return new ArrayList<T>(s); won't work, since s isn't the same type as that new ArrayList being created. You also can't take a bunch of objects that are instances of a supertype of T and return a collection that's T. Imagine if s were List<Object> and t were a String. Your method would be required to return a List<String>, which is impossible unless you somehow know that all the objects in s are secretly strings.

Also, why are you adding t to s and then returning a new ArrayList that's just s? You're modifying s by doing that.

What you should probably do is

public static <T> List <T> add(List<T> s, T t) {
    List<T> res = new ArrayList<>(s);
    res.add(t);
    return res;
}

You could also do this if t's type could be less specific than the elements in s.

public static <T> List <T> add(List<? extends T> s, T t) {
    List<T> res = new ArrayList<>(s);
    res.add(t);
    return res;
}

Upvotes: 3

Related Questions