"no primitives in container" 规则是否适用于数组?

Does the "no primitives in container" rule apply to arrays?

我最近一直在尝试实现一个简单的遗传算法。我需要使用存储 (Character,4 bits) 对的可逆映射。我为此任务选择了 Guava 的 BiMap。但是,由于我为位存储选择了 int 数组,因此测试不会通过。

int[]是原始类型吗?使用 VectorList 整数是否更适合此任务?

Is int[] primitive type?

没有。 Java 数组不是原始类型,即使它们的单个元素是原始类型也是如此。

Will using vector or list of integers be appropriate tool for such task?

Vector<T>List<T> 都无法在没有 "boxing" 的情况下将原语存储到包装器中。但是,如果您只需要四位,则可以使用一个 byte,它有八位可用于存储。

要从 byte 中提取位 k,请使用 (b & (1 << k)) != 0 表达式。当此表达式的计算结果为 true 时,位 k 设置为 1;否则,它被设置为 0.

要将字节中的位 k 设置为 1,请使用 b |= (1 << k)。要将位 k 重置为 0,请使用 b &= ~(1 << k)

你的问题不在于 int[] 是原始的。 Java 中的数组是一个对象。问题是它是一个对象 ,它不会覆盖 hashCode()equals() 方法

因为它没有覆盖它们,所以它们与 Object 的相同,其中对象只有在相同(即对同一实例的引用)时才相等。

基本上:

int[] a = new int[] {1,1,1,1};
int[] b = new int[] {1,1,1,1};
System.out.println( a.equals(b) );

你可能期望它打印 true,但它会打印 false,因为你创建了两个不同的数组,它检查数组是否是同一个对象,而不是它们的内容是否相同是一样的!

很有可能,如果您还添加

System.out.println( a.hashCode() );
System.out.println( b.hashCode() );

您还将获得两个不同的哈希码。

因此,数组不太适合用于检查 equality/uniqueness 的集合。它们与标准 Map 中的 value 一样好,但不如 key。在 Guava BiMap 中,它们既不能用作键也不能用作值。

你应该怎么做?

您应该使用覆盖 equals()hashCode() 的对象,这样如果内容相同,equals() returns true 和两者从 hashCode() 返回相同的值。

如果你想要相对紧凑的东西,你可以用 Byte 对象来表示这些位。您可以使用位操作运算符。

或者您可以使用 BitSet,它是 Java 位的标准容器。

小心,因为 BitSet 是可变的。可变对象在哈希表等对值敏感的数据结构中使用时可能表现不佳,因为大多数实现无法判断您何时更改了值,因此它们无法相应地在哈希桶中移动它。一旦对象存储在 BiMap!

中,不要设置或清除对象中的任何位