Let's take an example to make it easier. I build a list which the constructor takes an integer
and a List<Integer>
. My list will contains all the elements of the given list multiplied by the integer
. My list does not store the new elements but compute them on the fly:
class MyList extends AbstractList<Integer> implements RandomAccess {
private final int multiplier;
private final List<Integer> list;
public MyList(int multiplier, List<Integer> list) {
this.multiplier = multiplier;
this.list = list;
}
@Override
public Integer get(int index) {
return list.get(index) * multiplier;
}
@Override
public int size() {
return list.size();
}
}
Then we can call new MyList(3, list)
with list = [0, 1, 2, 3]
to get [0, 3, 6, 9]
.
I would like to limit the developer to give to the MyList
constructor a list which is also RandomAccess
, to be sure he will not ruin performances.
I tried to change the constructor with:
public <E extends List<Integer> & RandomAccess> MyList(int multiplier, E list)
MyList
is not the issue but now we cannot invoke the constructor without using an implementation of both List<Integer>
and RandomAccess
like ArrayList<Integer>
. So someone who have this list: List<Integer> list = new ArrayList<>();
cannot do new MyList(3, list);
(Because it is declared with List<Integer>
instead of ArrayList<Integer>
).
The other solution I have is this one:
public MyList(int multiplier, List<Integer> list) {
if(!(list instanceof RandomAccess)) {
// Do something like log or throw exception
}
this.multiplier = multiplier;
this.list = list;
}
But now I cannot check at compile time if the list implements RandomAccess
, and I need to use instanceof
and I hate doing this.
I'm pretty sure there is a better way but what is it?
RandomAccess
"to be sure he will not ruin performances", then why would you still want to allow them to invoke your constructor withList
, which clearly doesn't implementRandomAccess
? Is this just for cosmetic reason? – CoplanarList.get()
. – Savor