3

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

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

4

2 回答 2

5

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

因为它不覆盖它们,所以它们与 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() );

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

出于这个原因,数组不太适合在检查相等/唯一性的集合中使用。它们可以作为标准中的Map,但不能作为关键。在 Guava 中BiMap,它们既不能用作键,也不能用作值。

你该怎么办?

您应该使用覆盖equals()and的对象,hashCode()以便如果内容相同,则equals()返回并从两者true返回相同的值。hashCode()

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

或者您可以使用一个BitSetJava 标准的比特容器。

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

于 2015-07-11T20:29:37.580 回答
2

int[]原始类型吗?

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

使用向量或整数列表是否适合此类任务?

Vector<T>如果不List<T>将它们“装箱”到包装器中,也不能存储原语。但是,如果您只需要 4 位,则可以使用单个byte,它有 8 位可用于存储。

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

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

于 2015-07-11T19:51:45.203 回答