我最近一直在尝试实现一个简单的遗传算法。我需要使用存储成对的可逆映射(Character,4 bits)
。BiMap
我为这项任务选择了番石榴。int
但是,由于我为位存储选择了一个数组,测试不会通过。
是int[]
原始类型吗?使用 aVector
或List
整数是否更适合此任务?
你的问题不是那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
对象来表示这些位。您可以使用位操作运算符。
或者您可以使用一个BitSet
Java 标准的比特容器。
小心,因为BitSet
它是可变的。可变对象在像哈希表这样的值敏感数据结构中使用时可能表现不佳,因为大多数实现无法判断您何时更改了值,因此它们无法相应地在哈希桶中移动它。一旦对象存储在BiMap
!
是
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)
。重置位k
以0
使用b &= ~(1 << k)