Bri*_*ris 9 java iterator guava
我正在编写GC友好代码来读取并向用户返回一系列byte[]消息.在内部我重复使用ByteBuffer它,这意味着我将在大多数时间重复返回相同的byte[]实例.
我正在考虑编写警示javadoc并将其暴露给用户作为Iterator<byte[]>.AFAIK它不会违反Iterator合同,但如果他们这样做Lists.newArrayList(myIterator)并且在每个位置回到List人口中,那么用户肯定会感到惊讶byte[]!
问题:对于可能变异并返回相同对象来实现接口的类,这是不好的做法吗?Iterator
两个小调:
我正在使用Guava,AbstractIterator因此remove()并不是真正值得关注的问题.
在我的用例中,用户就是我,这个类的可见性将受到限制,但我已经尝试过这个问题,通常可以更广泛地应用.
更新:我接受路易斯的答案,因为它的票数比基思多3倍,但请注意,在我的用例中,我打算采用我留下的代码来评论基思对生产的回答.
Lou*_*man 10
EnumMap在它的entrySet()迭代器中基本上完成了这一点,这导致了令人困惑,疯狂,令人沮丧的错误.
如果我是你,我就不会使用Iterator- 我会写一个不同的API(可能与Iterator完全不同,甚至)并实现它.例如,你可以写一个新的API,如需要输入的ByteBuffer写的留言到,因此API的用户可以控制的缓冲区是否得到重用.这似乎相当直观(用户可以编写明显且干净地重用的ByteBuffer代码),而不会产生不必要的混乱代码.
我会定义一个你可以无效的中间对象.所以你的函数会返回一个Iterator<ByteArray>,ByteArray就像这样:
class ByteArray {
private byte[] data;
ByteArray(byte[] d) { data = d; }
byte[] getData() {
if (data == null) throw new BadUseOfIteratorException();
return data;
}
void invalidate() { data = null; }
}
Run Code Online (Sandbox Code Playgroud)
然后,您的迭代器可以使之前返回的无效,ByteArray以便将来的任何访问(通过getData您提供的任何其他访问者)都将失败.然后,至少如果某人做了类似的事情Lists.newArrayList(myIterator),他们至少会得到一个错误(当ByteArray访问第一个无效时),而不是静默地返回错误的数据.
当然,这不会捕获所有可能的不良用途,但可能是常见的用途.如果您对永远不会返回原始数据byte[]并提供类似的访问器感到满意byte get(int idx),那么它应该能够捕获所有情况.
你必须ByteArray为每个迭代器返回分配一个新的,但希望这比复制你byte[]的每个迭代器返回要便宜得多.
| 归档时间: |
|
| 查看次数: |
561 次 |
| 最近记录: |