- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在设计一个简单的类子类化 ArrayList<Color>
.在我的应用程序上下文中,此列表充当“引用列表”,返回 Color
遵循循环且定义明确的顺序的对象。
@SuppressWarnings("serial")
public final class ColorList extends ArrayList<Color> {
private static int colorIndex = -1;
public ColorList() {
this.add(Color.CYAN);
this.add(Color.DARK_GRAY);
this.add(Color.GRAY);
this.add(Color.GREEN);
this.add(Color.BLUE);
this.add(Color.LIGHT_GRAY);
this.add(Color.MAGENTA);
this.add(Color.ORANGE);
this.add(Color.PINK);
this.add(Color.RED);
this.add(Color.YELLOW);
}
//if the color chosen is not the last one, increment index and get it.
public Color getNextColor() {
Color color = null;
if(colorIndex != this.size() - 1) {
color = this.get(++colorIndex);
}
else {
colorIndex = -1;
color = this.get(++colorIndex);
}
return color;
}
出于这个原因,我想让这个类不可变,因为它旨在成为一个只读列表,其内容在对象首次实例化时定义,并在其整个生命周期内保持不变。同时,我需要能够利用 getNextColor()
保持“循环”时尚。
采取的方法
返回不可修改的引用。
public static List<Color> getInstance(){
return Collections.unmodifiableList(new ColorList());
}
这种方法的问题在于,通过返回一个 List 引用它阻止我调用 getNextColor()
方法,使我的类无用。转换并不能解决问题,因为底层对象是一个UnmodifiableRandomAccessList
的实例并且不能转换为 ColorList
.
覆盖引用可选操作的方法
@Override
public boolean add(Color c) {
throw new UnsupportedOperationException("color list is read-only");
}
<overridding other methods such as addAll, remove...>
如 documentation 中所述,一些标记为“可选”的操作可能会或可能不会根据集合的目的来实现。但这会阻止我首先添加颜色,就像我在实例化对象时在构造函数中所做的那样。
我想我可能误解了一些关键的设计方面。有没有办法让我的类不可变,而不限制其(已经是基本的)功能?
编辑:出于向后兼容性的原因,要求此类显式扩展 ArrayList。因此我不能使用包装类,尽管我也认为这是最正确的方法。
最佳答案
如果你希望 List 的内容是不可变的,那么你的构造函数就可以工作,只是你应该调用 super.add(...)
而不是 this.add (...)
;这样做意味着您对 add(...)
的覆盖将是明智的,可以保护列表免受外部干扰,同时允许构造函数为您初始化对象。
你的问题不清楚,但如果你还想阻止直接访问列表中的对象,你显然也可以重写 get(...)
和其他适当的方法 - 尽管如果你做,那么你的 getNextColor(...)
方法应该调用 super.get(...)
而不是 this.get(...)
.
最后,您可能不需要 colors
成员变量,因为您正在扩展一个 List - 没有必要在其中嵌套另一个 List。
关于java - 创建 ArrayList 的不可变子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50189773/
我是一名优秀的程序员,十分优秀!