A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 孙百鑫 于 2013-3-28 23:16 编辑

/*
每一个学生都有对应的归属地.
学生Student,地址String
学生属性.姓名.年龄.
注意.:姓名和年龄相同的视为同一个学生.
保证学生的唯一性.
1. 描述学生.
2.定义map容器.将学生作为键,地址作为值,存入.
3.获取map集合中的元素.
*/
import java.util.*;
class Student implements Comparable<Student>//实现Comparable接口明确类型
{
private String name;
private int age;
Student(String name,int age)
{
  this.name=name;
  this.age=age;
}
public int compareTo(Student s)//明确比较类型 ,比较的是Student
{
  int num=new Integer(this.age).compareTo(new Integer(s.age));//比较年龄如果小于,排左边.大于排右边.
  if(num==0)//如果相等笔记姓名
   return this.name.compareTo(s.name);
  return num;//最后返回姓名
}
public int hashCode()//这句话也不理解?????????????????????????????????????????????????????????????????????????
{
  return name.hashCode()+age*34;//什么意思啊??????????????????????????????????????????????????????????????
}
public boolean equals(Object obj)//传进去的类型不匹配,所以用Object
{
  if(!(obj instanceof Student))//如果Obj和Student不相等的话抛出异常
   throw new ClassCastException("类型不匹配");
  Student s=(Student)obj;//把obj强制转换成Student学生
  return this.name.equals(s.name) && this.age==s.age;//这句话什么意思啊?????????????????????????????????????
}
public String getName()
{
  return name;
}
public int getAge()
{
  return age;
}
public String toString()
{
  return name+".."+age;
}
}

class MapTest
{
public static void main(String[] args)
{
  HashMap<Student,String> hm=new HashMap<Student,String>();
  hm.put(new Student("lisi1",21),"beijing");
  hm.put(new Student("lisi2",22),"shaghan");
  hm.put(new Student("lisi3",23),"nanjing");
  hm.put(new Student("lisi4",24),"wuhan");
  //第一种取出方式 keySet
  Set<Student> keySet=hm.keySet();
  Iterator<Student> it=keySet.iterator();
  while(it.hasNext())
  {
   Student stu=it.next();
   String addr=hm.get(stu);
   System.out.println(stu+".."+addr);
  }
}
}

点评

如果你的问题已经得到解决,请及时将主题改为[已解决],如果还有问题请继续追问,谢谢!  发表于 2013-3-28 08:30

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1 赞一个!

查看全部评分

21 个回复

倒序浏览
Comparable 可比较的   此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序。
compareTo(T o)比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

回复 使用道具 举报
实现 Comparable 接口中的 compareTo 方法,
通常大于时返回一个正数,小于时返回一个负数,
等于时返回零。
int num=new Integer(this.age).compareTo(new Integer(s.age));//比较this.age和S.age.要相等返回零赋给num,下面if判断
if(num==0)
                        return this.name.compareTo(s.name);
                return num;

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

回复 使用道具 举报
于腾飛 发表于 2013-3-28 00:04
实现 Comparable 接口中的 compareTo 方法,
通常大于时返回一个正数,小于时返回一个负数,
等于时返回零 ...

返回负数.和返回正数是还有0是什么意思啊???
回复 使用道具 举报
张宝 发表于 2013-3-28 00:01
Comparable 可比较的   此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序。
co ...

如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数是什么意思啊
回复 使用道具 举报
孙百鑫 发表于 2013-3-28 00:09
返回负数.和返回正数是还有0是什么意思啊???

返回负数时什么意思 ?你开玩笑呢是吧
回复 使用道具 举报
于腾飛 发表于 2013-3-28 00:25
返回负数时什么意思 ?你开玩笑呢是吧

我知道正数为真.负数为假.可是有什么作用啊?
回复 使用道具 举报
张宝 中级黑马 2013-3-28 00:30:00
8#
如果该对象小于指定对象,返回负整数,那么该对象就排在指定对象的左边
如果该对象大于指定对象,返回负整数,那么该对象就排在指定对象的右变
回复 使用道具 举报
孙百鑫 发表于 2013-3-28 00:28
我知道正数为真.负数为假.可是有什么作用啊?

if(num==0)
                        return this.name.compareTo(s.name);//这个
                return num;
这不是紧接着的IF判断语句嘛,要是num==0 就return嘛
回复 使用道具 举报
孙百鑫 发表于 2013-3-28 00:28
我知道正数为真.负数为假.可是有什么作用啊?

注意.:姓名和年龄相同的视为同一个学生.
保证学生的唯一性.
public int hashCode()
        {
                return name.hashCode()+age*34;//姓名和年龄相同的话,hashcode()返回值相同
        }
     public int compareTo(Student s)//保证学生对象的唯一性
        {
                int num=new Integer(this.age).compareTo(new Integer(s.age));

                if(num==0)//年龄相同,再比较姓名
                        return this.name.compareTo(s.name);//姓名也相同,则表示为同一学生对象
                return num;
        }

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

回复 使用道具 举报
于腾飛 发表于 2013-3-28 00:35
if(num==0)
                        return this.name.compareTo(s.name);//这个
                retu ...

别的都理解了.就差这三个了.....回来再看一下吧.....我修改了
回复 使用道具 举报
杨政 发表于 2013-3-28 00:37
注意.:姓名和年龄相同的视为同一个学生.
保证学生的唯一性.
public int hashCode()

别的都理解了.就差这三个了.....回来再看一下吧.....我修改了
回复 使用道具 举报
杨政 发表于 2013-3-28 00:37
注意.:姓名和年龄相同的视为同一个学生.
保证学生的唯一性.
public int hashCode()

别的都理解了.就差这三个了.....回来再看一下吧.....我修改了
回复 使用道具 举报
张宝 发表于 2013-3-28 00:30
如果该对象小于指定对象,返回负整数,那么该对象就排在指定对象的左边
如果该对象大于指定对象,返回负整 ...

别的都理解了.就差这三个了.....回来再看一下吧.....我修改了
回复 使用道具 举报
你代码中的问号都被我以注释的形式写出来了,你可以参考一下。多看看毕老师讲的视频,自己多体会体会,多看看笔记,我学这一段的时候也是想了很久才想明白的,还有一定要多看API文档。

  1. <P> import java.util.*;

  2. class Student implements Comparable<Student>
  3. /*
  4. 当一个对象被存入到集合中时,它可以被存入到List与Map中去。如果把他存入到TreeSet或者TreeMap等底层为二叉树结构的集合中时,存入的元素必须要有有可比性!让元素实现可比性的两个方法:1 让存入的对象(例如本例中的Student类就是被存入集合中的元素)本身具有可比性,即实现Comparable接口,2 在构造TreeSet或TreeMap时,传入比较器Comparator对象。
  5. 如果集合是ArrayList的话,Student类其实根本不用实现Comparable接口,因为ArrayList底层是数组结构,按照自己的编号排序。
  6. 如果集合是HashSet或者HashMap的话,Student类照样也不用实现Comparable接口,因为它们底层是Hash值,按照自身的Hash值进行排序。
  7. 让Student类实现Comparable接口的目的,其实只是为了避免Student类被存入到了二叉树结构的集合中。
  8. 在你这个代码中,最后将Students类存入到了HashMap中,其实完全可以不让Students实现Comparable接口。
  9. */
  10. {
  11. private String name;
  12. private int age;

  13. Student(String name,int age)
  14. {
  15. this.name=name;
  16. this.age=age;
  17. }
  18. public int compareTo(Student s)
  19. /*
  20. 这句话没什么意思。Students类实现了Comparable接口,就要复写Comparable接口中的comparTo方法。不理解的话可以看一下老毕的视频,day07中有关于接口的详细讲解。你自己再查阅一下API文档java.lang.Comparable就能知道了。
  21. */
  22. {
  23. int num=new Integer(this.age).compareTo(new Integer(s.age));
  24. /*
  25. 查看API文档,Comparable.compareTo()方法的返回值为int。这句话是什么意思呢?new Integer(this.age).compareTo(new Integer(s.age))其实就是往集合中每存入一个Students类,就把存入的Students的age值与集合中已经存在的Students对象的age值相减!如new Integer(3).compareTo(new Integer(2))=1,详见API文档java.lang.Integer的compareTo方法。
  26. 其实num的值完全也可以写作 this.age - s.age
  27. */

  28. if(num==0)
  29. /*
  30. 这句话是说,如果即将存入的Students的age值与集合中某一个Students类的age值相同,那么就让他们的另一个属性,即name属性进行比较。使用的同样也是String类的compareTo方法。String类的compareTo方法是将字符串按字典顺序相减。如: "abc".compareTo("abb")=1
  31. */
  32. return this.name.compareTo(s.name);

  33. return num;
  34. }

  35. public int hashCode()
  36. /*
  37. 这个是为了保证元素在存入到底层为Hash值的集合时不重复。HashSet和HashMap的底层都是Hash值结构,通过hash值来保证元素的唯一。
  38. 当Students对象被存入到HashSet或者HashMap中时, hm.put(new Student("lisi1",21),"beijing"),这时new Student("lisi1",21)作为一个匿名对象出现,这个对象会有自己的一个Hash值(具体Hash值的算法我也不知道)。当你再往集合中存入new Student("lisi1",21)时,又会在内存中出现一个匿名对象,他们的Hash值是不同的!所以,如果你的Students类不复写hashCode方法,这两个new Student("lisi1",21),"beijing")都会被存入进去!
  39. 但是当你复写了hashCode方法以后,这两个匿名对象都不会按照以前的那个方法计算hash值了,而是按照你给定的方法计算各自的hash值。
  40. */
  41. {
  42. return name.hashCode()+age*34;
  43. /*
  44. 这个是指你想让Students类怎样计算自己的Hash值。默认Hash值的算法是很麻烦的,基本上new一个对象就有一个hash值。但是你自己手动复写了hash值算法,让他们只比较姓名和年龄,这样的话hash值就会相同。例如:new Student("lisi1",21),如果按照默认的算法,hash值为11223344,当你再new一个Student("lisi1",21),按照默认算法,hash值可能就变成了33445566。但是你的目的是想让姓名年龄相同视为同一个人,所以你就让他们的只比较姓名和年龄这两个元素就可以了。
  45. age*34是为了Hash值偶然相同。比方说,"lisi"字符串的Hash值为40,年龄为20, 而"wangwu"字符串的hash值为32,年龄为28,name.hashCode()+age都等于60.为了避免出现这样的情况,让就age随便乘以一个基数,那样 40+20*34就不再等于32+28*34了
  46. */
  47. }

  48. public boolean equals(Object obj)
  49. /*
  50. 当Hash值相同时,才会调用equals方法对照内容进行比较。比方说,"lisi".hashCode()=40,age =20, "wangwu".hashCode()=720,age=0,那么lisi.hashCode()+age*34正好等于 wangwu.hashCode()+age*34,但是这两个人却不是同一个人!所以此时就需要调用equals方法对内容进行比较!
  51. */
  52. {
  53. if(!(obj instanceof Student))
  54. throw new ClassCastException("类型不匹配");

  55. Student s=(Student)obj;

  56. return this.name.equals(s.name) && this.age==s.age;
  57. //对学生的姓名和年龄进行比较,如果返回为true,那就说明这个学生已经存入到了集合中,不会再存入,即集合中已经有了一个lisi,20,反之,则存入
  58. }
  59. public String getName()
  60. {
  61. return name;
  62. }
  63. public int getAge()
  64. {
  65. return age;
  66. }
  67. public String toString()
  68. {
  69. return name+".."+age;
  70. }
  71. }


  72. class MapTest
  73. {
  74. public static void main(String[] args)
  75. {
  76. HashMap<Student,String> hm=new HashMap<Student,String>();

  77. hm.put(new Student("lisi1",21),"beijing");
  78. hm.put(new Student("lisi2",22),"shaghan");
  79. hm.put(new Student("lisi3",23),"nanjing");
  80. hm.put(new Student("lisi4",24),"wuhan");

  81. //第一种取出方式 keySet

  82. Set<Student> keySet=hm.keySet();

  83. Iterator<Student> it=keySet.iterator();

  84. while(it.hasNext())
  85. {
  86. Student stu=it.next();
  87. String addr=hm.get(stu);
  88. System.out.println(stu+".."+addr);
  89. }
  90. }
  91. </P>
复制代码

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

回复 使用道具 举报
姜伟 发表于 2013-3-28 01:35
你代码中的问号都被我以注释的形式写出来了,你可以参考一下。多看看毕老师讲的视频,自己多体会体会,多看 ...

万分感谢.超级大神!!!!!要的就是这种超级详细的答案..太爱你了.困扰了我一晚上了..终于理解通了.!!!!太不容易了.加我扣扣被.以后有问题帮帮我.283122529谢谢啦
回复 使用道具 举报
孙百鑫 发表于 2013-3-28 01:50
万分感谢.超级大神!!!!!要的就是这种超级详细的答案..太爱你了.困扰了我一晚上了..终于理解通了.!!!!太不 ...

我也是零基础才学完的,前几天面试的,发挥的不太好,不知道能不能被录取。
回复 使用道具 举报
姜伟 发表于 2013-3-28 01:53
我也是零基础才学完的,前几天面试的,发挥的不太好,不知道能不能被录取。 ...

好流弊啊你.......肯定能面试上啊. ....你学了 多久了呀..这么狠
回复 使用道具 举报
孙百鑫 发表于 2013-3-28 02:09
好流弊啊你.......肯定能面试上啊. ....你学了 多久了呀..这么狠

我学了多久我都不好意思说,自制力太差了。我刚开始以为他们只是走走形式,所以没怎么在乎,自荐信只得了八分,面试又没发挥好,所以总分不高,又很少逛论坛,技术分又不够,现在在恶补技术分。分数不高,心里不高兴,有些自责,所以这么晚了还睡不下。这些东西其实都不是太难的,关键是要你自己去想。我跟你说的这些话都是老毕说过的,只是没有写下来,我在看视频的时候觉得哪儿重要,就把它记下来了,十分钟的视频我得看半个小时。多记笔记,有些时候他随意的一句话就很重点,一定要记下来。还有就是要一定要多看API文档,看不懂也要看。共勉
回复 使用道具 举报
姜伟 发表于 2013-3-28 02:19
我学了多久我都不好意思说,自制力太差了。我刚开始以为他们只是走走形式,所以没怎么在乎,自荐信只得了 ...

还是真的很谢谢你...你扣扣多少呀...我加你
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马