Java中有ImmutableBitSet吗?
是否有任何 Java 库提供 ImmutableBitSet
?我没有找到任何东西,无论是 Guava 还是使用 Google。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
是否有任何 Java 库提供 ImmutableBitSet
?我没有找到任何东西,无论是 Guava 还是使用 Google。
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(7)
您可以使用 BigInteger,因为它具有 <代码>setBit、
testBit
和clearBit
。You could use BigInteger, since it has
setBit
,testBit
andclearBit
.我决定对所有答案进行总结:
我认为没有办法让一切变得完美,即获得
BitSet
的不可变子类,以便equals
在线程安全的方式。我承认我没有在问题中说出我的所有要求。继承
BitSet
并让所有的 mutator 方法抛出异常既简单又有效。唯一的问题是从 BitSet 调用的 equals 本身不是线程安全的,因为它直接访问非最终继承字段。所有其他方法都可以通过下面描述的技巧变得线程安全。委托给
BitSet
也很简单并且有效,唯一的问题是BitSet
不能等于ImmutableBitSet
。请注意,为了线程安全,委托必须存储在最终字段中。将继承和委托结合起来看起来很有前途:
它看起来很奇怪,但工作起来近乎完美。对 bitSet.equals(immutableBitSet) 的调用不是线程安全的,因为它们直接访问非最终字段。所以这只是一次徒劳的练习。
如果想要实现所有方法以及与可变 BitSet 之间的转换,那么使用 BitInteger 是一项相当大的工作。因此,我建议使用委托或继承,具体取决于
equals
所需的行为以及线程安全的需要。I decided to make a summary of all the answers:
I see no way to get everything perfect, i.e., to get an immutable subclass of
BitSet
, so thatequals
works in an thread-safe manner. I admit that I didn't state all my requirements in the question.Inheriting from
BitSet
and letting all the mutator methods throw an exception is easy and works. The only problem is thatequals
called fromBitSet
itself is not thread-safe since it accesses the non-final inherited fields directly. All other methods can be made thread-safe by a trick described below.Delegating to
BitSet
is also easy and works, and its only problem is that aBitSet
can't be equal to anImmutableBitSet
. Note that for thread safety the delegate must be stored in a final field.Combining inheritance and delegation looks promising:
It looks strange, but works nearly perfect. Call to
bitSet.equals(immutableBitSet)
are not thread-safe, because of them accessing the non-final fields directly. So it was just a fruitless exercise.Using a
BitInteger
is quite a lot of work if one wants to implement all the methods and conversion to and from the mutable BitSet. So I'd recommend either delegation or inheritance, depending on the desired behavior ofequals
and on the need for thread safety.解决方法:
将 BitSet 存储在私有字段中并使用克隆公共方法公开它:
或者:
A workaround:
store the BitSet in a private field and expose it with a cloning public method:
or:
通过扩展java.util.BitSet并使用抛出UnsupportedException或空块删除修饰符方法,可以很容易地从java.util.BitSet创建一个几乎不可变的BitSet。
然而,由于 BitSet 存储有效数据的字段不是最终,因此您必须应用一种安全发布习惯用法来实现线程安全(复制自 此处):
一把锁。
另一种解决方案可能是创建一个新的 ImmutableBitSet 类,将 BitSet 作为字段嵌入到其中(使用 Final 修饰符),并将嵌入对象的读取器方法委托给新类。
请注意,后一个解决方案不会违反 Liskow 替换原则,而第一个解决方案则违反了。
It's easy to make a practically immutable BitSet from a java.util.BitSet by extending it and knock out modifier methods with throws UnsupportedException or empty block.
However, since BitSet's field which stores effective data isn't final, you have to apply one of the safe publication idioms to achieve thread-safety (copied from here):
a lock.
Another solution could be to make a new ImmutableBitSet class, embed a BitSet into it as a field (with final modifier) and delegate the embedded object's reader methods to the new class.
Note that the latter solution doesn't break Liskow Substitution Principle while the first one does.
您也许可以使用 BigInteger。它是不可变的,并且具有位操作方法。
You could maybe use BigInteger. It is immutable, and has bit manipulation methods.
就我个人而言,我更喜欢
EnumSet
而不是BitSet
。它被实现为一个位字段,但具有一组强命名的 API。确实,这是两全其美的。 Guava 确实提供了一个ImmutableEnumSet
Personally, I prefer an
EnumSet
over aBitSet
. It is implemented as a bit field, but has the API of a set with strong naming. Really this is the best of both worlds. Guava does provide anImmutableEnumSet
我已经基于 Apache Lucene 项目中的 org.apache.lucene.util.OpenBitSet 实现了此类功能,位于
http://www. dishevelled.org/bitset
http://www.dishevelled.org/bitset/apidocs/index.html
I have implemented such based on org.apache.lucene.util.OpenBitSet from the Apache Lucene project here
http://www.dishevelled.org/bitset
http://www.dishevelled.org/bitset/apidocs/index.html