我需要创建一个非常类似于String的类,但是不是存储一个字符数组,该对象必须存储一个字节数组,因为我将处理二进制数据,而不是字符串。
我在我的应用程序中使用HashMaps。因此,我热衷于使我的自定义byteArray类不可变,因为不可变对象在哈希映射中执行更快的搜索。 (我想请一个这个事实的来源)
我很确定我的类是不可变的,但它在hashmap搜索中仍然表现不佳。我如何确定它是不可变的?
答案 0 :(得分:2)
最重要的是将字节复制到数组中。如果你有
this.bytes = passedInArray;
调用者可以修改passInArray,从而修改this.bytes。你必须做
this.bytes = Arrays.copyOf(passedInArray, passedInArray.length);
(或类似,克隆也是o.k.)。如果这个类主要用作Maps中的键,我会立即计算哈希码(在构造函数中),比懒惰更简单。
实施明显的equals()
,我认为你已经完成了。
答案 1 :(得分:2)
你的问题是"我怎样才能确定我的班级是不可改变的?"我不确定你的意思是什么,但是Josh Bloch在 Effective Java,2nd Ed。第15项中列出了使你的类不可变的方法{{ 3}},我将在这个答案中总结:
请注意,不可变对象不会自动产生巨大的性能提升。不可变对象的提升可能来自于不必锁定或复制对象,以及重用它而不是创建新对象。我相信HashMap中的搜索使用了这个类' hashCode()
方法,查找应该是O(c)
,或者是恒定时间和快速。如果您遇到性能问题,可能需要查看hashCode()
方法的速度是否缓慢(不太可能),或其他问题。
一种可能性是,如果你实施hashCode()
很差(或根本没有),这会导致HashMap
中的大量冲突 - 也就是说,使用不同的实例调用该方法您的类返回大部分相似或相同的值 - 然后实例将存储在hashCode()
指定的位置的链接列表中。遍历此列表会将您的效率从恒定时间转换为线性时间,从而使性能更差。
答案 2 :(得分:0)
因为不可变对象在哈希映射中执行更快的搜索。 (我想请一个这个事实的来源)
不,这不是真的。作为hashmap键的性能将由hashCode
的运行时和冲突避免决定。
我很确定我的类是不可变的,但它在hashmap搜索中仍然表现不佳。我如何确定它是不可变的?
您的问题更有可能成为hashCode
实施的糟糕选择。考虑将您的实施基于Arrays.hashCode
。
(您的问题ArrayList<Byte> vs String in Java表明您正在尝试调整特定的实现;使用byte[]
的建议很好。)