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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© IT_JM 中级黑马   /  2013-10-10 09:01  /  849 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

第四讲     Set
一、概述
        Set:元素是无序(存入和取出的顺序不一定一致),元素不可以重复。     
           |--HashSet:底层数据结构是哈希表。线程不同步。 保证元素唯一性的原理:判断元素的hashCode值是否相同。如果相同,还会继续判断元素的equals方法,是否为true。
           |--TreeSet:可以对Set集合中的元素进行排序。默认按照字母的自然排序。底层数据结构是二叉树。保证元素唯一性的依据:compareTo方法return 0。
        Set集合的功能和Collection是一致的。
二、HasSet
        HashSet:线程不安全,存取速度快。
       可以通过元素的两个方法,hashCode和equals来完成保证元素唯一性。如果元素的HashCode值相同,才会判断equals是否为true。如果元素的hashCode值不同,不会调用equals。
注意:HashSet对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashCode和equals方法。
示例:
  1. 1. /*
  2. 2. 往hashSet集合中存入自定对象
  3. 3. 姓名和年龄相同为同一个人,重复元素。去除重复元素
  4. 4. 思路:1、对人描述,将人的一些属性等封装进对象
  5. 5. 2、定义一个HashSet容器,存储人对象
  6. 6. 3、取出
  7. 7.
  8. 8. */
  9. 9. import java.util.*;
  10. 10.
  11. 11. //人描述
  12. 12. class Person
  13. 13. {
  14. 14. private String name;
  15. 15. private int age;
  16. 16.
  17. 17. Person(String name,int age)
  18. 18. {
  19. 19. this.name=name;
  20. 20. this.age=age;
  21. 21. }
  22. 22.
  23. 23. public String getName()
  24. 24. {
  25. 25. return name;
  26. 26. }
  27. 27.
  28. 28. public int getAge()
  29. 29. {
  30. 30. return age;
  31. 31. }
  32. 32.
  33. 33. public boolean equals(Object obj)
  34. 34. {
  35. 35. if(!(obj instanceof Person))
  36. 36. return false;
  37. 37. Person p=(Person)obj;
  38. 38. return this.name.equals(p.name)&&this.age==p.age;
  39. 39. }
  40. 40.
  41. 41. public int hashCode()
  42. 42. {
  43. 43. return this.name.hashCode()+this.age;
  44. 44. }
  45. 45. }
  46. 46. class HashSetTest
  47. 47. {
  48. 48. public static void main(String[] args)
  49. 49. {
  50. 50. HashSet h=new HashSet();
  51. 51. h.add(new Person("shenm",10));
  52. 52. h.add(new Person("shenm2",6));
  53. 53. h.add(new Person("shenm1",30));
  54. 54. h.add(new Person("shenm0",10));
  55. 55. h.add(new Person("shenm0",10));
  56. 56.
  57. 57. getOut(h);
  58. 58.
  59. 59. }
  60. 60.
  61. 61. //取出元素
  62. 62. public static void getOut(HashSet h)
  63. 63. {
  64. 64. for (Iterator it=h.iterator(); it.hasNext(); )
  65. 65. {
  66. 66. Person p=(Person)it.next();
  67. 67. sop(p.getName()+"..."+p.getAge());
  68. 68. }
  69. 69. }
  70. 70.
  71. 71. //打印
  72. 72. public static void sop(Object obj)
  73. 73. {
  74. 74. System.out.println(obj);
  75. 75. }
  76. 76. }
复制代码
三、TreeSet
1、特点
        a、底层的数据结构为二叉树结构(红黑树结构)
        b)可对Set集合中的元素进行排序,是因为:TreeSet类实现了Comparable接口,该接口强制让增加到集合中的对象进行了比较,需要复写compareTo方法,才能让对象按指定需求(如人的年龄大小比较等)进行排序,并加入集合。
        java中的很多类都具备比较性,其实就是实现了Comparable接口。
注意:排序时,当主要条件相同时,按次要条件排序。
二叉树示意图
file:///C:/Users/dou/AppData/Roaming/Tencent/Users/281665334/QQ/WinTemp/RichOle/Q%7DJ$T$6XPECKF)A4(ILZ%60PT.jpg
        c、保证数据的唯一性的依据:通过compareTo方法的返回值,是正整数、负整数或零,则两个对象较大、较小或相同。相等时则不会存入。
2、Tree排序的两种方式
        1)第一种排序方式:自然排序
        让元素自身具备比较性。元素需要实现Comparable接口,覆盖compareTo方法。这种方式也被称为元素的自然顺序,或者叫做默认顺序。
示例:
  1. 1. import java.util.*;
  2. 2. //学生类
  3. 3. class Student implements Comparable
  4. 4. {
  5. 5. private String name;
  6. 6. private int age;
  7. 7. Student(String name,int age)
  8. 8. {
  9. 9. this.name=name;
  10. 10. this.age=age;
  11. 11. }
  12. 12. public String getName()
  13. 13. {
  14. 14. return name;
  15. 15. }
  16. 16.
  17. 17. public int getAge()
  18. 18. {
  19. 19. return age;
  20. 20. }
  21. 21. //复写hashCode以便HashSet集合调用
  22. 22. public int hashCode()
  23. 23. {
  24. 24. return name.hashCode()+age;
  25. 25. }
  26. 26. //复写equals以便HashSet集合和集合中一些比较方法调用
  27. 27. public boolean equals(Object obj)
  28. 28. {
  29. 29. if(!(obj instanceof Student))
  30. 30. throw new RuntimeException();
  31. 31. Student s = (Student)obj;
  32. 32. return this.name.equals(s.name)&&this.age==s.age;
  33. 33. }
  34. 34. //复写compareTo以便TreeSet集合调用
  35. 35. public int compareTo(Object obj)
  36. 36. {
  37. 37. Student s=(Student)obj;
  38. 38. if(this.age==s.age)
  39. 39. return this.name.compareTo(s.name);
  40. 40. return this.age-s.age;
  41. 41. //return new Integer(this.age).compareTo(new Integer(s.age));
  42. 42. }
  43. 43. }
  44. 44.
  45. 45. class TreeSetTest
  46. 46. {
  47. 47. public static void main(String[] args)
  48. 48. {
  49. 49. TreeSet<Student> t=new TreeSet<Student>();
  50. 50. t.add(new Student("wo1",12));
  51. 51. t.add(new Student("wosj",2));
  52. 52. t.add(new Student("wo1sdj",12));
  53. 53. t.add(new Student("wo6sd",12));
  54. 54. t.add(new Student("wo",22));
  55. 55.
  56. 56.
  57. 57. for (Iterator<Student> it=t.iterator(); it.hasNext(); )
  58. 58. {
  59. 59. Student s=it.next();
  60. 60. System.out.println(s.getName()+"....."+s.getAge());
  61. 61. }
  62. 62. }
  63. 63. }
复制代码
2)第二种方式:比较器
        当元素自身不具备比较性时,或者具备的比较性不是所需要的。这时就需要让集合自身具备比较性。
        在集合初始化时,就有了比较方式。定义一个比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。
        比较器构造方式:定义一个类,实现Comparator接口,覆盖compare方法。
        当两种排序都存在时,以比较器为主。
示例:
  1. 1. /*
  2. 2. 需求:
  3. 3. 往TreeSet集合中存储自定义对象学生。
  4. 4. 想按照学生的年龄进行排序。
  5. 5.
  6. 6. */
  7. 7.
  8. 8. import java.util.*;
  9. 9. //学生类
  10. 10. class Student implements Comparable
  11. 11. {
  12. 12. private String name;
  13. 13. private int age;
  14. 14. Student(String name,int age)
  15. 15. {
  16. 16. this.name=name;
  17. 17. this.age=age;
  18. 18. }
  19. 19. public String getName()
  20. 20. {
  21. 21. return name;
  22. 22. }
  23. 23.
  24. 24. public int getAge()
  25. 25. {
  26. 26. return age;
  27. 27. }
  28. 28. //复写hashCode以便HashSet集合调用
  29. 29. public int hashCode()
  30. 30. {
  31. 31. return name.hashCode()+age;
  32. 32. }
  33. 33. //复写equals以便HashSet集合和集合中一些比较方法调用
  34. 34. public boolean equals(Object obj)
  35. 35. {
  36. 36. if(!(obj instanceof Student))
  37. 37. throw new RuntimeException();
  38. 38. Student s = (Student)obj;
  39. 39. return this.name.equals(s.name)&&this.age==s.age;
  40. 40. }
  41. 41. //复写compareTo以便TreeSet集合调用
  42. 42. public int compareTo(Object obj)
  43. 43. {
  44. 44. Student s=(Student)obj;
  45. 45. if(this.age==s.age)
  46. 46. return this.name.compareTo(s.name);
  47. 47. return this.age-s.age;
  48. 48. //return new Integer(this.age).compareTo(new Integer(s.age));
  49. 49. }
  50. 50.
  51. 51. }
  52. 52.
  53. 53. class TreeSetTest
  54. 54. {
  55. 55. public static void main(String[] args)
  56. 56. {
  57. 57. TreeSet<Student> t=new TreeSet<Student>(new LenCompare());
  58. 58. t.add(new Student("wo1",12));
  59. 59. t.add(new Student("wosj",2));
  60. 60. t.add(new Student("wo1sdj",12));
  61. 61. t.add(new Student("wo6sd",12));
  62. 62. t.add(new Student("wo",22));
  63. 63.
  64. 64.
  65. 65. for (Iterator<Student> it=t.iterator(); it.hasNext(); )
  66. 66. {
  67. 67. Student s=it.next();
  68. 68. System.out.println(s.getName()+"....."+s.getAge());
  69. 69. }
  70. 70. }
  71. 71.
  72. 72. }
  73. 73. //定义一个比较器,以姓名长度为主要比较
  74. 74. class LenCompare implements Comparator<Student>
  75. 75. {
  76. 76. public int compare(Student s1,Student s2)
  77. 77. {
  78. 78. int num=new Integer(s1.getName().length()).compareTo(new Integer(s2.getName().length()));
  79. 79. if (num==0)
  80. 80. {
  81. 81. return new Integer(s1.getAge()).compareTo(s2.getAge());
  82. 82. }
  83. 83. return num;
  84. 84. }
  85. 85. }
复制代码


评分

参与人数 1技术分 +1 收起 理由
黄文伯 + 1 非常好!

查看全部评分

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马