Java中有ImmutableBitSet吗?

发布于 2024-11-29 01:45:04 字数 84 浏览 1 评论 0 原文

是否有任何 Java 库提供 ImmutableBitSet ?我没有找到任何东西,无论是 Guava 还是使用 Google。

Is there any Java library offering an ImmutableBitSet? I didn't find any, neither Guava nor using Google.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

等你爱我 2024-12-06 01:45:04

您可以使用 BigInteger,因为它具有 <代码>setBit、testBitclearBit

You could use BigInteger, since it has setBit, testBit and clearBit.

总攻大人 2024-12-06 01:45:04

我决定对所有答案进行总结:

我认为没有办法让一切变得完美,即获得 BitSet 的不可变子类,以便 equals 在线程安全的方式。我承认我没有在问题中说出我的所有要求。

继承 BitSet 并让所有的 mutator 方法抛出异常既简单又有效。唯一的问题是从 BitSet 调用的 equals 本身不是线程安全的,因为它直接访问非最终继承字段。所有其他方法都可以通过下面描述的技巧变得线程安全。

委托给 BitSet 也很简单并且有效,唯一的问题是 BitSet 不能等于 ImmutableBitSet。请注意,为了线程安全,委托必须存储在最终字段中。

将继承和委托结合起来看起来很有前途:

public class ImmutableBitSet extends BitSet {
    private final ImmutableBitSet delegate;

    public ImmutableBitSet(BitSet original) {
        or(original); // copy original to this
        delegate = this; // initialize a final reference for thread safety
    }

    @Override // example mutator method
    public void and(BitSet set) {
        throw new UnsupportedOperationException();
    }

    @Override // example non-mutator method
    public boolean get(int bitIndex) {
        return delegate.getPrivate(bitIndex);
    }

    // needed in order to avoid endless recursion
    private boolean getPrivate(int bitIndex) {
        super.get(bitIndex);
    }

    ...
}

它看起来很奇怪,但工作起来近乎完美。对 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 that equals 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 that equals called from BitSet 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 a BitSet can't be equal to an ImmutableBitSet. Note that for thread safety the delegate must be stored in a final field.

Combining inheritance and delegation looks promising:

public class ImmutableBitSet extends BitSet {
    private final ImmutableBitSet delegate;

    public ImmutableBitSet(BitSet original) {
        or(original); // copy original to this
        delegate = this; // initialize a final reference for thread safety
    }

    @Override // example mutator method
    public void and(BitSet set) {
        throw new UnsupportedOperationException();
    }

    @Override // example non-mutator method
    public boolean get(int bitIndex) {
        return delegate.getPrivate(bitIndex);
    }

    // needed in order to avoid endless recursion
    private boolean getPrivate(int bitIndex) {
        super.get(bitIndex);
    }

    ...
}

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 of equals and on the need for thread safety.

能怎样 2024-12-06 01:45:04

解决方法:

将 BitSet 存储在私有字段中并使用克隆公共方法公开它:

private final BitSet bits;
public BitSet bits(){
    return (BitSet) bits.clone();
}

或者:

private final BitSet bits;
public BitSet bits(){
    BitSet clone = new BitSet();
    clone.or(bits);
    return clone;
}

A workaround:

store the BitSet in a private field and expose it with a cloning public method:

private final BitSet bits;
public BitSet bits(){
    return (BitSet) bits.clone();
}

or:

private final BitSet bits;
public BitSet bits(){
    BitSet clone = new BitSet();
    clone.or(bits);
    return clone;
}
情徒 2024-12-06 01:45:04

通过扩展java.util.BitSet并使用抛出UnsupportedException或空块删除修饰符方法,可以很容易地从java.util.BitSet创建一个几乎不可变的BitSet。

然而,由于 BitSet 存储有效数据的字段不是最终,因此您必须应用一种安全发布习惯用法来实现线程安全(复制自 此处):

  • 从静态初始化程序初始化对象引用;
  • 将对其的引用存储到易失性字段或 AtomicReference 中;
  • 将对它的引用存储到正确构造的对象的最终字段中
  • 将对其的引用存储到由以下对象正确保护的字段中
    一把锁。

另一种解决方案可能是创建一个新的 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):

  • Initializing an object reference from a static initializer;
  • Storing a reference to it into a volatile field or AtomicReference;
  • Storing a reference to it into a final field of a properly constructed object
  • Storing a reference to it into a field that is properly guarded by
    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.

宣告ˉ结束 2024-12-06 01:45:04

您也许可以使用 BigInteger。它是不可变的,并且具有位操作方法。

You could maybe use BigInteger. It is immutable, and has bit manipulation methods.

未蓝澄海的烟 2024-12-06 01:45:04

就我个人而言,我更喜欢 EnumSet 而不是 BitSet。它被实现为一个位字段,但具有一组强命名的 API。确实,这是两全其美的。 Guava 确实提供了一个 ImmutableEnumSet

Personally, I prefer an EnumSet over a BitSet. 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 an ImmutableEnumSet

时光瘦了 2024-12-06 01:45:04

我已经基于 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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文