繁体   English   中英

如何确定我的班级是一成不变的

[英]How can I be sure that my class is immutable

我需要创建一个非常类似于String的类,但是该对象必须存储一个字节数组,而不是存储字符数组,因为我将处理二进制数据,而不是字符串。

我在应用程序中使用HashMaps。 因此,我很想使我的自定义byteArray类不可变,因为不可变对象在哈希图中执行更快的搜索。 (我想要这个事实的消息来源)

我很确定我的课程是不可变的,但是在哈希映射搜索中,它与字符串相比仍然表现不佳。 如何确定它是不可变的?

最重要的是将字节复制到数组中。 如果你有

this.bytes = passedInArray;

调用方可以修改passedInArray,从而修改this.bytes。 必须

this.bytes = Arrays.copyOf(passedInArray, passedInArray.length);

(或者类似,克隆也可以)。 如果此类将主要用作Maps中的键,那么我会立即(在构造函数中)计算哈希码,这比懒惰地简单。

实现明显的equals() ,我认为您已经完成了。

您的问题是“我如何确定我的课堂是不变的?” 我不确定您要问的是什么意思,但是Josh Bloch在《 有效Java》第二版中列出了使类不可变的方法 这里的项目15中,我将在此答案中进行总结:

  1. 不要提供任何mutator方法(改变对象状态的方法,通常称为“ setters”)。
  2. 确保该类不能扩展。 通常,将课程定为最终课程。 这使其他人无法对其进行子类化和修改受保护的字段。
  3. 将所有字段定为最终字段,这样就无法更改它们。
  4. 将所有字段设为私有,以便其他人不能更改它们。
  5. “确保对可变组件的专有访问。” 也就是说,如果其他内容指向该数据并因此可以更改它,则进行防御性复制(如@ user949300所指出)。

请注意,不可变的对象不会自动产生很大的性能提升。 不可变对象的好处在于不必锁定或复制该对象,以及重新使用它而不是创建一个新对象。 我相信HashMap中的搜索使用该类的hashCode()方法,并且查找应为O(c)或恒定时间和快速速度。 如果您遇到性能问题,则可能需要查看hashCode()方法是否缓慢(不太可能)或其他地方是否存在问题。

一种可能性是,如果您实现的hashCode()很差(或根本没有实现),并且在HashMap引起大量冲突-也就是说,使用类的不同实例调用该方法将返回相似或相同的值- -然后,实例将存储在hashCode()指定的位置的链表中。 遍历此列表会将您的效率从恒定时间转换为线性时间,从而使性能变得更差。

因为不可变对象在哈希图中执行更快的搜索。 (我想要这个事实的消息来源)

不,这不是真的。 作为哈希映射键的性能将由hashCode的运行时以及避免冲突来确定。

我很确定我的课程是不可变的,但是在哈希映射搜索中,它与字符串相比仍然表现不佳。 如何确定它是不可变的?

您的问题很可能是对hashCode实现的错误选择。 考虑基于Arrays.hashCode实现您的实现。

(您的问题ArrayList <Byte> vs Java在Java中建议您尝试调整特定的实现;使用byte[]的建议很好。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM