zoukankan      html  css  js  c++  java
  • 关于JAVA核心技术(卷一)读后的思考(hashCode、toString方法的讨论)

    hashCode方法

    散列码(hashCode)是有对象导出的一个整型值。散列码是没有规律的。

    如果x和y是两个不同对象,x.hashCode()与y.hashCode()基本不会相同。String类使用下列算法计算散列码:

    int hash=0;
    for(int i=0;i<length();i++)
      hash=31*hash+charAt(i);

    由于hashCode方法定义在Object类中,故每个对象都有一个默认的散列码,其值为对象的存储地址。

    String s="Ok";
    StringBuilder sb=new StringBuilder(s);
    System.out.println(s.hashCode()+" "+sb.hashCode());
    String t=new String("Ok");
    StringBuilder tb =new StringBuilder(t);
    System.out.printkln(t.hashCode()+" "+tb.hashCode());

    通过运行结果发现s和t拥有相同的散列码,这时候就可以观察String类中对于hashCode()的定义了,就可以发现其散列码是与其值有关的,s和t二者值相同故散列码相同。

    而sb和tb不同,是因为StringBuilder是没有定义hashCode方法的,它的散列码是由Object类中继承下来的。即返回的是对象存储地址。

    这里还要提到上一篇提到的重新定义equals方法,如果要重新定义equals方法,必须重新定义hashCode方法。

    与此同时,equals方法和hashCode要保持一致,equals方法返回true的话,那么散列码值必须相同。

    在这里我想补充一点关于String、StringBuilder和StringBuffer方法的区别。

    1)String类是final类,也即意味着String类不能被继承,并且它的成员方法都默认为final方法。在Java中,被final修饰的类是不允许被继承的,并且该类中的成员方法都默认为final方法。在早期的JVM实现版本中,被final修饰的方法会被转为内嵌调用以提升执行效率。而从Java SE5/6开始,就渐渐摈弃这种方式了。因此在现在的Java SE版本中,不需要考虑用final去提升方法调用效率。只有在确定不想让该方法被覆盖时,才将方法设置为final。

    2)String类其实是通过char数组来保存字符串的。

    3)运行速度快慢为:StringBuilder > StringBuffer > String

    String最慢的原因:

    String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。

    4)在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的

    如果一个StringBuffer对象在字符串缓冲区被多个线程使用时,StringBuffer中很多方法可以带有synchronized关键字,所以可以保证线程是安全的,但StringBuilder的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。所以如果要进行的操作是多线程的,那么就要使用StringBuffer,但是在单线程的情况下,还是建议使用速度比较快的StringBuilder。

    toString方法

      在Object中另一个重要的方法就是toString方法,用于返回表示对象值的字符串。

    绝大多数的toString方法都遵循这样的格式类的名字,随后是一对方括号括起来的域值;eg:

    public String toString(){
    return "Employee[name="+name+",salary="+salary+",hireDay="+hireDay+"]";
    }

    实际上可以设计的更好一些。可以通过调用getClass().getName()获得类名的字符串,而不要将类名硬加到toString方法中。

    随处可见toString方法的主要原因是:只要对象一个字符串通过操作符“+”连接起来,Java编译就会自动的调用toString方法,以便获得这个对象的字符串描述。

    Point p =new Point(10,20);
    String message="The current position is"+p;

    这时候就会自动调用p.toString()方法;

    如果x是一个对象,并调用了System.out,println(x);

    则系统会自动调用x.toString()并输出相应的字符串。

    如果有写的不对的地方,欢迎指正,希望能够共同进步,谢谢!
  • 相关阅读:
    Qt Q3DScatter中元素的移动和旋转
    Qt QtDataVisualization Q3DScatter绘制散点图
    Qt qwtplot3d根据时间采集多条曲线
    Qt QWT3D 之 三维动态曲线的实现
    Qt 数据可视化之3D图形
    Vagrant在虚拟机Centos7上安装Docker
    VirtualBox+Vagrant环境搭建
    VMware安装Centos7超详细过程(图文)
    上传excel表格批量导入数据到数据库
    IP协议包头分析
  • 原文地址:https://www.cnblogs.com/zzuzhouxiang/p/10338935.html
Copyright © 2011-2022 走看看