您是否看过Java中Object类的javadoc? 大概。 您倾向于时不时地到达那里,然后沿着继承树进行挖掘。 您可能已经注意到的一件事是,每个类都必须继承许多方法。 实现自己而不是坚持使用原始方法的最喜欢的方法可能是.toString()、. equals()和.hashCode()( Per-ÅkeMinborg在本文中很好地描述了为什么应该始终实现这两种方法) )。

但是这些方法显然还不够。 许多人从标准库(如Comparable和Serializable)中混合使用其他接口。 但这真的很明智吗? 为什么每个人都想如此严重地自己实现这些方法? 好吧,如果您打算将它们存储在HashMap之类的文件中并希望控制哈希冲突,那么实现自己的.equals()和.hashCode()方法可能很有意义,但是compareTo()和toString()呢?

在本文中,我将介绍一种在Speedment开源项目中使用的软件设计方法,其中将对对象进行操作的方法实现为存储在变量中的功能引用,而不是覆盖内置在方法中的Java。 这有几个优点。 您的POJO将更短,更简洁,可以重复使用通用操作而无需继承,并且可以灵活地在不同配置之间进行切换。

原始码

让我们从下面的示例开始。 我们有一个典型的Java类,名为Person。 在我们的应用程序中,我们希望按Set的顺序打印每个人的名字,其后跟姓氏(以防两个人共享相同的名字)。

人.java

public class Person implements Comparable<Person> {private final String firstname;private final String lastname;public Person(String firstname, String lastname) {this.firstname = firstname;this.lastname  = lastname;}public String getFirstname() {return firstname;}public String getLastname() {return 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;}return Objects.equals(this.lastname, other.lastname);}@Overridepublic int compareTo(Person that) {if (this == that) return 0;else if (that == null) return 1;int comparison = this.firstname.compareTo(that.firstname);if (comparison != 0) return comparison;comparison = this.lastname.compareTo(that.lastname);return comparison;}@Overridepublic String toString() {return firstname + " " + lastname;}
}

Main.java

public class Main {public static void main(String... args) {final Set people = new HashSet<>();people.add(new Person("Adam", "Johnsson"));people.add(new Person("Adam", "Samuelsson"));people.add(new Person("Ben", "Carlsson"));people.add(new Person("Ben", "Carlsson"));people.add(new Person("Cecilia", "Adams"));people.stream().sorted().forEachOrdered(System.out::println);}
}

输出量

run:
Adam Johnsson
Adam Samuelsson
Ben Carlsson
Cecilia Adams
BUILD SUCCESSFUL (total time: 0 seconds)

Person在此处实现了几种方法来控制流的输出。 hashCode()和equals()方法确保不能将重复的人添加到集合中。 sorted操作使用compareTo()方法产生所需的顺序。 重写的toString()方法最终控制了在调用System.out.println()时应如何打印每个Person。 您认识这种结构吗? 您几乎可以在几乎所有的Java项目中找到它。

替代代码

除了将所有功能都放入Person类之外,我们还可以尝试使其尽可能保持清洁,并使用功能性引用来处理这些修饰。 我们使用equals,hashCode,compareTo和toString删除所有样板,而是引入两个静态变量COMPARATOR和TO_STRING。

人.java

public class Person {private final String firstname;private final String lastname;public Person(String firstname, String lastname) {this.firstname = firstname;this.lastname  = lastname;}public String getFirstname() {return firstname;}public String getLastname() {return lastname;}public final static Comparator<Person> COMPARATOR =Comparator.comparing(Person::getFirstname).thenComparing(Person::getLastname);public final static Function<Person, String> TO_STRING =p -> p.getFirstname() + " " + p.getLastname();
}

Main.java

public class Main {public static void main(String... args) {final Set people = new TreeSet<>(Person.COMPARATOR);people.add(new Person("Adam", "Johnsson"));people.add(new Person("Adam", "Samuelsson"));people.add(new Person("Ben", "Carlsson"));people.add(new Person("Ben", "Carlsson"));people.add(new Person("Cecilia", "Adams"));people.stream().map(Person.TO_STRING).forEachOrdered(System.out::println);}
}

输出量

run:
Adam Johnsson
Adam Samuelsson
Ben Carlsson
Cecilia Adams
BUILD SUCCESSFUL (total time: 0 seconds)

这种方法的好处是,我们现在可以在不更改Person类的情况下替换打印的顺序和格式。 这将使代码更易于维护,更易于重用,而不是说编写起来更快。

翻译自: https://www.javacodegeeks.com/2016/02/cleaner-responsibilities-get-rid-equals-compareto-tostring.html

清洁责任–摆脱均等,compareTo和toString相关推荐

  1. compareto 和_清洁责任–摆脱均等,compareTo和toString

    compareto 和 您是否看过Java中Object类的javadoc? 大概. 您倾向于时不时地到达那里,然后沿着继承树进行挖掘. 您可能已经注意到的一件事是,每个类都必须继承许多方法. 实现自 ...

  2. C# DateTime ToString

    From: http://www.cnblogs.com/yangdj2000/archive/2009/04/29/1446063.html 字符型转换为字符串 // C 货币  2.5.ToStr ...

  3. ToString函数用法

    // C 货币     2.5.ToString("C"); // ¥2.50     // D 10进制数     25.ToString("D5"); // ...

  4. java重载tostring_什么时候不希望在Java中实现toString()?

    什么时候不希望在Java中实现toString()? 我项目的一位主要开发人员已将项目的toString()实现称为"纯粹的残障",并希望将其从代码库中删除. 我已经说过,这样做意 ...

  5. C#学习-数值与日期的ToString()格式汇总

    起因 在开发过程中,涉及到通过使用枚举类型来优化接口.因为要与 入参/出参 做对比 对 出库/入库 string类型变量赋值等.其中的转换感觉实在不方便,甚是奇怪,既然被推荐转换成枚举做处理进行优化的 ...

  6. Java学习路线图,内附完整Java自学视频教程+工具经验

    Java学习路线图更新日志:         增加视频<2016最新视频struts2> 密码:vhfp(2016.11.10) 增加视频<6天玩转mysql视频> 密码:a8 ...

  7. Java_Web笔记汇总_火热更新中。。。

    零.历史和特点 1.历史 (1)作者:James-Gosling (2)主要发展历程 1995.5.23SUN公司 正式发布了Java语言 1996年1月 开发工具包JDK1.0 1997年2月 JD ...

  8. [转]C#日期格式化 文档

    日期转化一 为了达到不同的显示效果有时,我们需要对时间进行转化,默认格式为:2007-01-03 14:33:34 ,要转化为其他格式,要用到DateTime.ToString的方法(String, ...

  9. C#:String.Format数字格式化输出

    C#:String.Format数字格式化输出 int a = 12345678;    //格式为sring输出 //   Label1.Text = string.Format("asd ...

最新文章

  1. python函数中可变参数的传递方式是_Python函数可变参数定义及其参数传递方式实例详解...
  2. 操作系统:再见CentOS,将于本月底终止维护!
  3. anaconda在ubuntu中添加环境变量
  4. emui换鸿蒙内核,华为EMUI 11.1三月上线,安卓内核替换为鸿蒙内核
  5. Java基础知识之方法的通用格式、注意事项与带参数的方法
  6. 使用Python在指定文件夹新建一个文本文档(其他类型文件也可)
  7. 物联网15年,盘点国内崛起的智能产业
  8. GB 50007-2011《建筑地基基础设计规范》高清电子版
  9. 计算机前沿技术科论文,计算机前沿技术论文
  10. 使用urllib发起请求- urlopen发起请求read/decode/getcode/info/geturl-post请求抽屉网
  11. 铁路一线工人春运备战实录:深夜里的“钢铁工匠”
  12. 数胎动可辨别宝宝是不是缺氧
  13. 浅谈Attention机制
  14. ps4手柄驱动linux,Arduino和单片机区别,及Arduino入门教程
  15. 如何使用ghost制作系统镜像
  16. 在OTFS学习中的一些总结
  17. 机器学习入门的书单(数据挖…
  18. Firefox下载文件时中文名乱码问题
  19. 02 锁版本--通用模块--knife4j--profiles
  20. java futuretask 单例_集群环境下java单例查询多了就异常

热门文章

  1. 统一配置中心的设计方案
  2. 人生路漫漫,还得多输出
  3. 二叉排序树的删除+图解
  4. html图片通过照片查看器打开图片,在Windows7中打开照片,提示“Windows 照片查看器无法显示此图片,因为计算机上...
  5. 定西市计算机考试,2019年3月甘肃省定西市计算机等级考试时间
  6. 转: 深入浅出-网络七层模型
  7. XML—— 验证XML文档
  8. 静态资源Html基础语法
  9. aws上负载均衡器标组端口_AWS CloudFormation:目标组没有关联的负载均衡器
  10. payara 创建 集群_Apache Payara:让我们加密