黑马程序员技术交流社区

标题: 想知道字符串的地址是不是这个字符串的哈希值?如果是..... [打印本页]

作者: 王广亚    时间: 2013-9-4 11:18
标题: 想知道字符串的地址是不是这个字符串的哈希值?如果是.....
本帖最后由 王广亚 于 2013-9-4 11:21 编辑

想知道字符串的地址是不是这个字符串的哈希值?如果是的话请看下面视频中毕老师讲的。问题中有点自己的推理,有点长,请耐心看。
先做个验证:只要String s1=new String("abc");这样创建的字符串对象都是开辟了新的空间。String s2="abc";String s3="abc";只要前面有了s2,s3就不会开辟新的空间。

  1. <P>package toString;</P>
  2. <P>public class Xiangdeng {</P>
  3. <P> public static void main(String[] args) {
  4.   String a1="abc";
  5.   String a2="abc";
  6.   String a3=new String("abc");
  7.   String a4=new String("abc");
  8.   System.out.println((a1==a2)+"..."+(a1.equals(a2))+"..."+(a1==a3)+"..."+(a1.equals(a3))+"..."+(a3==a4)+"..."+(a3.equals(a4)));</P>
  9. <P> }</P>
  10. <P>}
  11. </P>
复制代码
接下来才是正题:

  1. <P>package exception;

  2. import java.util.*;
  3. public class HasCodeTest
  4. {
  5. public static void sop(Object obj)
  6. {
  7. System.out.println(obj);
  8. }
  9. public static void main(String[] args)
  10. {
  11. HashSet hs = new HashSet();

  12. hs.add(new Person1("a1",11));
  13. hs.add(new Person1("a2",12));//new Person("a2","12");当创建这个对象时要调用Person的构造函数,(请顺着我的思路转到构造方法的代码)
  14. hs.add(new Person1("a3",13));
  15. hs.add(new Person1("a2",12));//我的思路是从此处开始(请顺着思路走):因为是HashSet集合,这个集合里的值是不能重复的,当添加新的对象时会调用hashCode先判断这个对象的哈希值,哈希值一样再调用equals比较内容</P>
  16. <P>                                                 //两个结果都通过了是,就说明集合了已经有了这个元素,就不再往里添加。默认的hashCode判断的是对象的哈希值,equals判断的是地址值。所以要覆写他们。
  17.                                                   //(接下面话题)此处也相当于String name=“a2”;这样创建的字符串对象吧。既然上面添加的new Person1("a2",12));对象和这个是一样的说明他们是同一个地址值</P>
  18. <P>                                                //(请再跳到下面的hashCode方法)</P>
  19. <P>Iterator it = hs.iterator();
  20. while(it.hasNext())
  21. {
  22. Person1 p = (Person1)it.next();
  23. sop(p.getName()+"::"+p.getAge());
  24. }
  25. }
  26. }
  27. class Person1
  28. {
  29. private String name;
  30. private int age;
  31. Person1(String name,int age)//(接上面的据需说)把值传过来后相当于:String name=“a2”;(这写字符串这块,age于此问题无关就不说了),而不是String name=new String("a2");</P>
  32. <P>                                             //(请再转到上面的集合添加了第二个a2处——hs.add(new Person1("a2",12))
  33. {
  34. this.name = name;
  35. this.age = age;
  36. }

  37. public int hashCode()
  38. {
  39. System.out.println(this.name+"....hashCode");
  40. return name.hashCode()+age*37;// 因为上面的字符串创建方法就不能判断name.hashCode()返回的值是相同的了。(因为我问的第一个问题是“字符串的地址是不是这个字符串的哈希值”</P>
  41. <P>                                                      //当然这些话题都是在这个问题的结论成立的基础上)。那么,我如果把hashSet集合添加第二个hs.add(new Person1("a2",12));时改为</P>
  42. <P>                                                //hs.add(new Person1(new String("a2"),12));这样添加的话,是不是在判断name.hashCode()时他们就不是同一个值了,那么就会把这个new String("a2"),12));对象</P>
  43. <P>                                         //也添 加进hashSet集合了?,按这个逻辑推理应该是,对吧。但是运行时却不是这样的结果,他并没有添加进去,求解释。。。。。。。。。。。。。?</P>
  44. <P>                                           //随便提醒一下此处的name.hashCode()的hashCode是字符串覆写Object类后的字符串特有的方法,并没有他自己调用他自己。
  45. }

  46. public boolean equals(Object obj)
  47. {

  48. if(!(obj instanceof Person1))
  49. return false;

  50. Person1 p = (Person1)obj;
  51. System.out.println(this.name+"...equals.."+p.name);

  52. return this.name.equals(p.name) && this.age == p.age;
  53. }


  54. public String getName()
  55. {
  56. return name;
  57. }
  58. public int getAge()
  59. {
  60. return age;
  61. }
  62. }
  63. </P>
复制代码

作者: 吴光新    时间: 2013-9-4 13:02
我就只回答你题目的问题了,手机看帖不方便!
既然是字符串地址,它只是内存的一片空间的名称,不代表字符串的哈西值




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2