Let's look at an example to make it simpler. I create a list that the constructor accepts integer and List<Integer> . My list will contain all the elements of this list multiplied by integer . My list does not store new elements, but calculates 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 the RandomAccess constructor a list, which is also RandomAccess , so that it does not ruin the performance.
I tried changing the constructor with:
public <E extends List<Integer> & RandomAccess> MyList(int multiplier, E list)
MyList not a problem, but now we can not call the constructor without using the implementation of both List<Integer> and RandomAccess , like ArrayList<Integer> . So, someone who has this list: List<Integer> list = new ArrayList<>(); cannot do new MyList(3, list); (because it is declared with List<Integer> instead of ArrayList<Integer> ).
Another solution that I have is the following:
public MyList(int multiplier, List<Integer> list) { if(!(list instanceof RandomAccess)) {
But now I canβt check at compile time if the list implements RandomAccess , and I need to use instanceof , and I hate doing it.
I am sure there is a better way, but what is it?