我的问题与Java有关。由于可选方法,我不喜欢java.util
包。例如,我不喜欢它,当我返回List
时,我必须阻止用户修改列表;我想返回一个实现接口UnmodifiableList
的列表(是的,我知道Collections.unmodifiableList()
,但由于很多原因,我不喜欢封装我的列表)。另一方面,当我从一段外部代码中获得一个列表时,这个列表可能是a1)不可修改的,a2)可修改的副作用对象返回我的列表,或者a3)可修改而没有副作用和b1)不可变(假设列表中的元素也是不可变的)或b2)可变和不安全用作键。
我可以重写大多数现有的类(只需复制/粘贴java.util
包)并不费力地引入接口UnmodifiableList
,ModifiableList
等。但是,我有以下问题:我真的很喜欢forall机制
for (final Object o: listOfObjects) {
// do something
}
使用类java.lang.Iterable
,它使用java.util.Iterator
。
所以我的问题是,我应该如何应对Iterator
类?
我有几种可能的解决方案,但我正在寻找最优雅的解决方案。
Iterable
不同的类?java.util.Iterator.remove()
标记为已弃用?Iterator
时它们都会发出警告?我目前的计划是定义自己的Iterator
,作为java.util.Iterator
的扩展,并将remove()
方法标记为已弃用。接下来,我将有一些脚本查看我的代码,并确保java.util
无处使用(除了我自己的Iterator
的定义)。那样,我应该安全。
编辑:感谢您的建议和链接,伙计们。干杯。
答案 0 :(得分:5)
我不会明白(或缺乏)取代java.util.*
,但至于Iterable
和Iterator
:
你不能在foreach循环中替换 Iterable
- 它实际上是在Java编译器中硬编码的。
当可选操作不受支持时,Java规范允许抛出非常精细的UnsupportedOperationException
。这有什么问题?如果您的测试套件有适当的覆盖范围,那么无论如何您都会立即知道。几个Java接口(Abstract*
)的抽象实现默认为不支持的操作抛出异常。
如果您的代码试图从不支持它的Collection中删除对象,那么您可能遇到的问题莫过于决定如何处理remove()
。如果您将集合传递给第三方代码,如果违反Java接口,将中断。
您总是可以使用一种方法覆盖remove()
,该方法不会消除任何错误......如果您可以在代码中意外破坏,而这些代码需要移除
答案 1 :(得分:1)
您可能有兴趣阅读官方常见问题解答,其中解释了为Java馆藏做出的一些设计选择:http://download.oracle.com/javase/1.4.2/docs/guide/collections/designfaq.html#1
进行可选操作有很好的理由。如果您真的希望编译器支持来管理类型的可变性,那么最好的办法是使用Scala及其Collection库。 Scala的类型系统更适合检查这些约束。
答案 2 :(得分:1)
如果要从方法返回列表,但又不想让方法的用户更改代码中使用的列表,则始终可以返回列表的副本:
return new ArrayList<?>(oldArrayList);
与使用标准API相比,重写整个集合库不太可能让您最终获得性能更好且易于维护的程序。