Hap*_*ppy 6 java collections list random-access
让我们举个例子来简化它.我构建了一个构造函数采用的列表integer和a List<Integer>.我的列表将包含给定列表的所有元素乘以integer.我的列表不存储新元素,而是动态计算它们:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
然后,我们可以调用new MyList(3, list)与list = [0, 1, 2, 3]获得[0, 3, 6, 9].
我想限制开发人员给MyList构造函数一个列表,这也是RandomAccess为了确保他不会破坏性能.
我尝试用以下方法更改构造函数:
public <E extends List<Integer> & RandomAccess> MyList(int multiplier, E list)
Run Code Online (Sandbox Code Playgroud)
MyList不是问题,但现在我们不能在不使用两者List<Integer>和RandomAccess类似的实现的情况下调用构造函数ArrayList<Integer>.所以有这个列表的人:List<Integer> list = new ArrayList<>();不能这样做new MyList(3, list);(因为它是用声明List<Integer>而不是ArrayList<Integer>).
我的另一个解决方案就是这个:
public MyList(int multiplier, List<Integer> list) {
if(!(list instanceof RandomAccess)) {
// Do something like log or throw exception
}
this.multiplier = multiplier;
this.list = list;
}
Run Code Online (Sandbox Code Playgroud)
但是现在我无法在编译时检查列表是否实现RandomAccess,我需要使用instanceof而且我讨厌这样做.
我很确定有更好的方法,但它是什么?
您可以采用 所使用的解决方案Collections.unmodifiableList。使用一个静态方法来代替公共构造函数,该方法返回两个实现之一,一个实现RandomAccess,另一个不实现。
这是 的代码Collections.unmodifiableList。
public static <T> List<T> unmodifiableList(List<? extends T> list) {
return (list instanceof RandomAccess ?
new UnmodifiableRandomAccessList<>(list) :
new UnmodifiableList<>(list));
}
Run Code Online (Sandbox Code Playgroud)
我知道你说过你不喜欢使用instanceof. 我也不知道,但有时这是最好的做法。
请注意,使用构造函数的解决方案
public <E extends List<Integer> & RandomAccess> MyList(int multiplier, E list)
Run Code Online (Sandbox Code Playgroud)
不仅丑陋,因为它迫使程序员强制转换(例如转换为ArrayList),但它实际上不起作用。例如,如果list是 的实例Collections$UnmodifiableRandomAccessList,则甚至无法将其转换为同时实现List和 的类型RandomAccess,因为Collections$UnmodifiableRandomAccessList它是私有的。