和谐 平等

将对象存储在集合中时,同一对象永远不能添加两次很重要。 这是集合的核心定义。 在Java中,使用两种方法来确定两个引用的对象是否相同,或者它们都可以存在于同一Set中。 equals()和hashCode()。 在本文中,我将解释平等与同一性之间的区别,并探讨它们在彼此之间所具有的一些优势。

Java提供了这两种方法的标准实现。 标准的equals()方法被定义为“身份”比较方法。 这意味着它将比较两个内存引用以确定它们是否相同。 因此,存储在内存中不同位置的两个相同的对象将被视为不相等。 如果使用Object类的源代码,可以使用==-operator进行比较。

public boolean equals(Object obj) {return (this == obj);
}

hashCode()方法由虚拟机作为本机操作实现,因此在代码中不可见,但通常将其实现为简单地返回内存引用(在32位架构上)或以32位模表示内存引用(在64位体系结构上)。

许多程序员在设计类时选择要做的一件事就是用不同的相等性定义覆盖此方法,在该方法中,您不查看比较内存引用,而是查看两个实例的值以查看它们是否可以相等。 这是一个例子:

import java.util.Objects;
import static java.util.Objects.requireNonNull;public final class Person {private final String firstname;private final String lastname;public Person(String firstname, String lastname) {this.firstname = requireNonNull(firstname);this.lastname  = requireNonNull(lastname);}@Overridepublic int hashCode() {int hash = 7;hash = 83 * hash + Objects.hashCode(this.firstname);hash = 83 * hash + Objects.hashCode(this.lastname);return hash;}@Overridepublic boolean equals(Object obj) {if (this == obj) return true;if (obj == null) return false;if (getClass() != obj.getClass()) return false;final Person other = (Person) obj;if (!Objects.equals(this.firstname, other.firstname)) {return false;} else return Objects.equals(this.lastname, other.lastname);}
}

这种比较称为“平等”(与之前的“身份”相比)。 只要两个人的名字和姓氏相同,就将被视为相等。 例如,这可以用于从输入流中筛选出重复项。 请记住,如果您覆盖equals()方法,则还应该始终覆盖hashCode()方法!

平等

现在,如果您选择平等而非身份,则需要考虑一些事项。 您必须问自己的第一件事是:具有相同属性的此类的两个实例是否一定相同? 对于上述人员,我会拒绝。 有一天,您的系统中很有可能会有两个姓氏和名字相同的人。 即使您继续添加更多的个人信息,例如生日或喜欢的颜色,您迟早也会发生冲突。 另一方面,如果您的系统正在处理汽车,并且每辆汽车都包含对“模型”的引用,则可以安全地假定,如果两辆汽车都是黑色Tesla S模型,则即使对象是汽车,它们也可能是同一模型。存储在内存中的不同位置。 这是平等可能很好的一个例子。

import java.util.Objects;
import static java.util.Objects.requireNonNull;public final class Car {public static final class Model {private final String name;private final String version;public Model(String name, String version) {this.name    = requireNonNull(name);this.version = requireNonNull(version);}@Overridepublic int hashCode() {int hash = 5;hash = 23 * hash + Objects.hashCode(this.name);hash = 23 * hash + Objects.hashCode(this.version);return hash;}@Overridepublic boolean equals(Object obj) {if (this == obj) return true;if (obj == null) return false;if (getClass() != obj.getClass()) return false;final Model other = (Model) obj;if (!Objects.equals(this.name, other.name)) {return false;} else return Objects.equals(this.version, other.version);}}private final String color;private final Model model;public Car(String color, Model model) {this.color = requireNonNull(color);this.model = requireNonNull(model);}public Model getModel() {return model;}
}

如果两辆汽车的内存地址相同,则它们被认为是相同的。 另一方面,只要它们具有相同的名称和版本,则认为它们的模型相同。 这是一个例子:

final Car a = new Car("black", new Car.Model("Tesla", "Model S"));
final Car b = new Car("black", new Car.Model("Tesla", "Model S"));System.out.println("Is a and b the same car? " + a.equals(b));
System.out.println("Is a and b the same model? " + a.getModel().equals(b.getModel()));// Prints the following:
// Is a and b the same car? false
// Is a and b the same model? true

身分识别

选择平等而不是身份的一种风险是,它可能会导致分配比堆上更多的对象。 只需看上面的汽车示例。 对于我们创建的每辆汽车,我们还为模型分配内存中的空间。 即使java通常优化了字符串分配以防止重复,对于始终相同的对象仍然是一定的浪费。 将内部对象转换为可以使用身份比较方法进行比较并同时避免不必要的对象分配的一个简单技巧是将其替换为枚举:

public final class Car {public enum Model {TESLA_MODEL_S ("Tesla", "Model S"),VOLVO_V70     ("Volvo", "V70");private final String name;private final String version;Model(String name, String version) {this.name    = name;this.version = version;}}private final String color;private final Model model;public Car(String color, Model model) {this.color = requireNonNull(color);this.model = requireNonNull(model);}public Model getModel() {return model;}
}

现在我们可以确定每种模型只会在内存中的某个位置存在,因此可以使用身份比较安全地进行比较。 然而,与此有关的一个问题是,这实际上限制了我们的可扩展性。 在此之前,可以在不修改Car.java文件中的源代码的情况下即时定义新模型的方法,但是现在我们已经将自己锁定在一个枚举中,该枚举通常应该保持不变。 如果需要这些属性,那么对等比较可能更适合您。

最后一点,如果您重写了类的equals()和hashCode()方法,后来又想根据身份将其存储在Map中,则始终可以使用IdentityHashMap结构。 即使equals()和hashCode()方法已被覆盖,它也会使用内存地址来引用其键。

翻译自: https://www.javacodegeeks.com/2016/03/equality-vs-identity.html

和谐 平等

和谐 平等_平等还是认同?相关推荐

  1. 和谐平等_并非所有观点都是平等的

    和谐平等 This blog post is a reaction to this blog post by David Hansson. If you have the time, I highly ...

  2. 暴君专栏和谐按钮_质量工具:卑微的仆人还是暴君?

    暴君专栏和谐按钮 我一直是软件内部质量的热心拥护者,因为根据我的各种经验,我需要维护的代码库不只这些. 我相信,高质量的工具可以提高代码的内部质量,从而从长远来看降低维护成本. 但是,我不认为此类工具 ...

  3. 社会平等对于中国计算机发展,平等思想的发展历程及对中国现实的分析

    摘要: 平等思想作为建构理想社会的基本价值取向和原则,在人类思想史上源远流长,人们对于平等的追求与探索也从未间断过. 本文主要立足于平等观念的发展历程,对西方平等思想的发展轨迹进行粗浅地梳理,结合西方 ...

  4. 对机会平等与结果平等的思考

    摘抄1 教育公平包括三个层面的含义:一是机会平等,即人人都有机会接受平等的教育:二是过程平等,即在接受教育过程中平等地享受教育资源:三是结果平等,即最终的教育结果应当体现出平等."融合教育, ...

  5. 夜空中最亮的星:慕课网新手学习指南_慕课手记

    首先标题是为了凑够标准的十个字,如果你这会去数了一下然后想评论说不是十个字,那我佩服你的求知精神...进来的肯定不是看我瞎扯淡的,我们步入正题. 慕课网作为国内不能说是最大,但是起码口碑最好的一个IT ...

  6. HR招聘_(二)_招聘方法论(招聘原因及原则)

    1 招聘原因离职 转岗 新增 工作量加大而无法负荷(若为短期工作量的加大可考虑外包或临时雇员) 业务发展需求(新产品线拓展,新事业部组建或组织架构变化等)2 招聘原则平等 面试官和候选人双方地位平等, ...

  7. 什么样的流_量最容易变现?

    积累足够信任和价值输出的流_量,最易变现.很多流_量要么是垃圾流_量,要么只是数据好看,图一热闹而已,都不值得去经营. 积累可信任的流_量,每一个流_量都认同认可你的价值观,因为认同而产生深度沟通,因 ...

  8. 新版标准日本语中级_第三十一课

    语法   1. 男性用语:在男性之间的对话中,称呼.句尾形式.打招呼或应答等有时会使用一些很有特点的说法.这些说法比较随便,只用于关系亲近的人之间.   1) 称呼:称自己おれ,称对方おまえ. おれは ...

  9. javascript运算符_返回基础:JavaScript运算符,条件和函数

    javascript运算符 在研究使用JavaScript创建程序之前,必须牢牢掌握基础知识. 在本文中,我们将介绍JavaScript的一些最重要的基本概念,这些基本概念使您可以开始编写自己的程序: ...

最新文章

  1. phppage类封装分页功能_封装page分页类
  2. springboot 获取application参数_LOOK ! SpringBoot的外部化配置最全解析
  3. Linux中sudo配置
  4. mysql特别点_Mysql 特别注意点!
  5. CentOS7.0 OpenWrt环境搭建
  6. 前端学习(2634):修改webstrom颜色
  7. 2022年中国折叠屏手机市场洞察报告
  8. 解读年度数据库性能:PostgreSQL的日志文件和数据加载
  9. 暴力测试也疯狂——论Python代码优化
  10. mysql 权限管理无效_mysql 权限控制笔记
  11. python黑白图片上色_百度AI攻略:黑白图像上色
  12. 天体运行轨迹_都说运动是天体的基本特性,那么银河系是绕着什么运动的呢?...
  13. 信号和通信系统第三版(PDF)
  14. EF批量添加数据BulkInsert
  15. 关于数据元、元数据、主数据、交易数据、主题数据、数据资源、大数据、数据湖等数据相关概念理解和总结
  16. [BZOJ4556]-[Tjoi2016Heoi2016]字符串-后缀自动姬+线段树合并+倍增
  17. html修改网站图标,分享内容,分享图标等
  18. 小霸王其乐无穷~FC红白机游戏600合集(支持mac 12.x系统)
  19. linux 中断子系统
  20. python开发系统架构设计师_系统架构设计师岗位自我评价怎么写

热门文章

  1. P3793-由乃救爷爷【分块,ST表】
  2. jzoj3337-[NOI2013模拟]wyl8899的TLE【字符串hash,二分】
  3. AtCoder Beginner Contest 183 总结
  4. 【数学】异或(jzoj 2298)
  5. hihocoder1147 时空阵(bfs树+DP)
  6. 6、java中的排序算法
  7. Http 持久连接与 HttpClient 连接池
  8. JVM内存管理------GC算法精解(复制算法与标记/整理算法)
  9. 彻底理解正向代理和反向代理
  10. (五)SpringBoot 能挣钱的几个项目!!!