Set集合为集类型。集是最简单的一种集合,存放于集中的对象不按特定方式排序,只是简单地把对象加入集合中。对集中存放的对象的访问和操作时通过对象的引用进行的,所以,在集中不能存放重复对象。

  Set接口实现了Collection接口,从而拥有Collection接口提供的所有常用方法。

  实现了Set接口的类有三种,分别是HashSet类(子类为LinkedHashSet类)、EnumSet类和TreeSet类。  

  1.HashSet类

  由HashSet类实现的Set集合的优点是能够快速定位集合中的元素。

  Set集合中的对象是无序的,遍历集合输出对象的顺序与向集合中插入对象的顺序并不相同。

  由HashSet类实现的Set集合中的对象必须是唯一的,所以,添加到由HashSet类实现的Set集合中的对象,需要重新实现equals()方法,从而保证插入集合中的对象的标识的唯一性。(Eclipse代码编辑区,右键-Source-Generate hashCode() and equals()...)

  由HashSet类实现的Set集合按照哈希码排序,根据对象的哈希码确定对象的存储位置,所以,添加到由HashSet类实现的Set集合中的对象,还需要重新实现hashCode()方法,从而保证插入集合中的对象能够合理地分布在集合中,以便于快速定位集合中的对象。(Eclipse代码编辑区,右键-Source-Generate hashCode() and equals()...)

  创建一个HashSet类的对象(Person类实现了hashCode()和equals()方法):

  1. Set<Person> hashSet = new HashSet<>();

  由于LinkedHashSet类是HashSet类的子类,如果既想保留HashSet类快速定位集合中对象的优点,又想让集合中的对象按插入的顺序保存,可以通过LinkedHashSet类来实现Set集合。

  1. Set<Person> hashSet = new LinkedHashSet<>();

  使用HashSet和LinkedHashSet实现Set集合的代码示例:

  1. package hashSet.jun.iplab;
  2.  
  3. import java.util.HashSet;
  4. import java.util.Iterator;
  5. import java.util.LinkedHashSet;
  6. import java.util.Set;
  7.  
  8. public class Person {
  9.  
  10. private String name;
  11. private long id_card;
  12.  
  13. public Person(String name, long id_card) {
  14. this.name = name;
  15. this.id_card = id_card;
  16. }
  17.  
  18. public String getName() {
  19. return name;
  20. }
  21.  
  22. public long getId_card() {
  23. return id_card;
  24. }
  25.  
  26. @Override
  27. public int hashCode() {
  28. final int prime = 31;
  29. int result = 1;
  30. /*由于最后的hashCode的类型是int, 而int只有32位,所以64位的Long值,
  31. * 要砍掉一半。为了不失去一半的信息,这个expression的意思是,
  32. * 会值的高32位和低32位的值进行exclusive OR的结果,
  33. * 这样就保证结果均会受前后32位的影响,不会丢失信息。
  34. * 如果直接把Long转成int, 那就会丢掉高32位的信息。
  35. * */
  36. result = prime * result + (int) (id_card ^ (id_card >>> 32));
  37. result = prime * result + ((name == null) ? 0 : name.hashCode());
  38. return result;
  39. }
  40.  
  41. @Override
  42. public boolean equals(Object obj) {
  43. if (this == obj)
  44. return true;
  45. if (obj == null)
  46. return false;
  47. if (getClass() != obj.getClass())
  48. return false;
  49. Person other = (Person) obj;
  50. if (id_card != other.id_card)
  51. return false;
  52. if (name == null) {
  53. if (other.name != null)
  54. return false;
  55. } else if (!name.equals(other.name))
  56. return false;
  57. return true;
  58. }
  59.  
  60. public static void main(String[] args) {
  61.  
  62. Set<Person> hashSet = new HashSet<>();
  63. hashSet.add(new Person("小红", 13211041));
  64. hashSet.add(new Person("小黄", 13211241));
  65. hashSet.add(new Person("小蓝", 13213231));
  66.  
  67. Iterator<Person> it_Person = hashSet.iterator();
  68. while (it_Person.hasNext()) {
  69. Person person = (Person) it_Person.next();
  70. System.out.println(person.getName() + " " + person.getId_card());
  71. }
  72. System.out.println();
  73.  
  74. Set<Person> linkedHashSet = new LinkedHashSet<>();
  75. linkedHashSet.add(new Person("小红", 13211041));
  76. linkedHashSet.add(new Person("小黄", 13211241));
  77. linkedHashSet.add(new Person("小蓝", 13213231));
  78.  
  79. Iterator<Person> it_LinkedHashSet_Person = linkedHashSet.iterator();
  80. while (it_LinkedHashSet_Person.hasNext()) {
  81. Person person = (Person) it_LinkedHashSet_Person.next();
  82. System.out.println(person.getName() + " " + person.getId_card());
  83. }
  84. }
  85.  
  86. }
  87.  
  88. 输出:
  89. 小蓝 13213231
  90. 小红 13211041
  91. 小黄 13211241
  92.  
  93. 小红 13211041
  94. 小黄 13211241
  95. 小蓝 13213231

  2.TreeSet类  

  TreeSet类不仅实现了Set接口,还实现了java.util.SortedSet接口,从而保证在遍历集合时按照递增的顺序获得对象。

  遍历对象时可能是按照自然顺序递增排列,所以,存入由TreeSet类实现的集合的对象必须实现Comparable接口;也可能是按照指定比较器递增排列,即可以通过比较器对由TreeSet类实现的Set集合中的对象进行排序。

  创建一个TreeSet类的对象为(其中Person实现了Comparable接口,因此必须实现compareTo方法):

  1. TreeSet<Person> treeSet = new TreeSet<>();

  TreeSet类由于实现了java.util.SortedSet接口而增加的一些常用方法:

  

  示例代码:

  • Person类中重写compareTo方法,按照id_card属性的大小进行访问排序,id_card大的返回1,相等返回0,小于返回-1
  1. // 重写compareTo方法,按照id_card的大小进行比较,如果大的返回1,等于返回0,小于返回-1
  2. @Override
  3. public int compareTo(Object o) {
  4. Person person = (Person) o;
  5. int result = id_card > person.id_card ? 1 : (id_card == person.id_card ? 0 : -1);
  6. return result;
  7. }
  • 首先创建五个Person对象并添加到TreeSet集合中
  1. Person person1 = new Person("小一", 13211123);
  2. Person person2 = new Person("小二", 13223131);
  3. Person person3 = new Person("小三", 13232412);
  4. Person person4 = new Person("小四", 13521312);
  5. Person person5 = new Person("小五", 13231231);
  6.  
  7. TreeSet<Person> treeSet = new TreeSet<>();
  8. treeSet.add(person1);
  9. treeSet.add(person2);
  10. treeSet.add(person3);
  11. treeSet.add(person4);
  12. treeSet.add(person5);
  • 迭代器访问时,将通过id_card的大小按照从小到大访问
  1. Iterator<Person> it = treeSet.iterator();
  2. while (it.hasNext()) {
  3. Person person = (Person) it.next();
  4. System.out.println(person.getName() + " " + person.getId_card());
  5. }
  6.  
  7. 输出:
  8. 小一 13211123
  9. 小二 13223131
  10. 小五 13231231
  11. 小三 13232412
  12. 小四 13521312
  • 通过headSet方法得到“小五”(不包括)前面部分的集合
  1. it = treeSet.headSet(person5).iterator();
  2. while (it.hasNext()) {
  3. Person person = (Person) it.next();
  4. System.out.println(person.getName() + " " + person.getId_card());
  5. }
  6.  
  7. 输出:
  8. 小一 13211123
  9. 小二 13223131
  • 通过subSet方法得到“小二”(包括)到“小四”(不包括)部分的集合
  1. it = treeSet.subSet(person2, person4).iterator();
  2. while (it.hasNext()) {
  3. Person person = (Person) it.next();
  4. System.out.println(person.getName() + " " + person.getId_card());
  5. }
  6.  
  7. 输出:
  8. 小二 13223131
  9. 小五 13231231
  10. 小三 13232412
  • 通过tailSet方法得到“小三”(包括)后面部分的集合
  1. it = treeSet.tailSet(person3).iterator();
  2. while (it.hasNext()) {
  3. Person person = (Person) it.next();
  4. System.out.println(person.getName() + " " + person.getId_card());
  5. }
  6.  
  7. 输出:
  8. 小三 13232412
  9. 小四 13521312

  二、Queue集合

  Queue是Collection接口的最后一个子接口。

  队列只允许在队尾

Java基础(二十二)集合(4)Set集合的更多相关文章

  1. java基础第十二篇之集合、增强for循环、迭代器和泛型

    Collection接口中的常用方法: * 所有的子类子接口都是具有的 * 集合的方法:增删改查 * * public boolean add(E e);//添加元素 返回值表示是否添加成功 * pu ...

  2. Java基础(十二):包(package)

    一.Java 包(package): 为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间.包的作用: 1.把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用. 2.如同文件夹 ...

  3. 夯实Java基础(十二)——异常处理

    1.异常处理概述 在Java程序执行过程中, 总是会发生不被期望的事件, 阻止程序按照程序员预期正常运行, 这就是Java程序出现的异常. 异常处理是基于面向对象的一种运行错误处理机制,通过对异常问题 ...

  4. java基础(十二章)

    一.变量的作用域(有效的使用范围) 1.变量有2种 1.1成员变量(属性) 声明在类的里面,方法的外面 1.2 局部变量 声明在方法里面或for循环结构中 2.调用时的注意事项(初始值不同.作用域不同 ...

  5. Java基础(十二)IO输入输出

    一.IO 概述 1.IO 概念 IO:I 代表 Input 输入:O 代表 Output 输出. Java 中 IO 是以流为基础进行输入输出,所有的数据被串行化(保存)写入输出流,或者从输入流读入. ...

  6. Java基础语法<十二> 泛型程序设计

    1 意义 泛型程序设计意味着编写的代码可以被很多不同类型的对象所重用. 常见应用 : ArrayList 2 K T V E ? object等的含义 类型变量使用大写形式 E – Element ( ...

  7. java基础(十二)常用类总结(二)

    这里有我之前上课总结的一些知识点以及代码大部分是老师讲的笔记 个人认为是非常好的,,也是比较经典的内容,真诚的希望这些对于那些想学习的人有所帮助! 由于代码是分模块的上传非常的不便.也比较多,讲的也是 ...

  8. Scanner、String(java基础知识十二)

    1.Scanner的概述和方法介绍 * A:Scanner的概述 * 是一个从键盘输入的类,有final修饰,不能被子类继承 * Scanner sc = new Scanner(System.in) ...

  9. Java基础(十二)lambda表达式

    1.引入lambda表达式的重要性 lambda表达式是一个可传递的代码块,可以在以后执行一次或多次. 在前面的回调部分,有一个例子是,ActionListener类实现了TimePrinter接口并 ...

  10. JAVA基础知识总结:一到二十二全部总结

    >一: 一.软件开发的常识 1.什么是软件? 一系列按照特定顺序组织起来的计算机数据或者指令 常见的软件: 系统软件:Windows\Mac OS \Linux 应用软件:QQ,一系列的播放器( ...

随机推荐

  1. Tomcat+Nginx+Linux+Mysql部署豆瓣TOP250的项目到腾讯云服务器

    写在前面 因为前面有写过一篇关于豆瓣的top250的电影的可视化展示项目,你可以移步http://blog.csdn.net/liuge36/article/details/78607955了解这个项 ...

  2. 《菜鸟程序员成长之路:从技术小白到阿里巴巴Java工程师》

    <菜鸟程序员成长之路:从技术小白到阿里巴巴Java工程师> 国庆节快乐!一年一度长度排第二的假期终于来了. 难得有十一长假,作者也想要休息几天啦. 不管你是选择出门玩,还是在公司加班,在学 ...

  3. jQuery三级联动效果代码(省、市、区)

    很长时间都不用jquery了,有人问我jquery写三级联动的插件我就写好了发出来吧,正好需要的人都可以看看. 一.html代码 <!DOCTYPE html> <html> ...

  4. SUSE CaaS Platform 4 - 安装部署

    SUSE CaaS Platform 相关文章 (1)SUSE CaaS Platform 4 - 简介 (2)SUSE CaaS Platform 4 - 安装部署 (3)SUSE CaaS Pla ...

  5. Hbase入门(四)——表结构设计-RowKey

    Hbase的表结构设计与关系型数据库有很多不同,主要是Hbase有Rowkey和列族.timestamp这几个全新的概念,如何设计表结构就非常的重要. 创建 Hbase就是通过 表 Rowkey 列族 ...

  6. [Python] Python 学习记录(2)

    1.range(x,y) [x,y) >>> range(0,4) #0,1,2,3 >>> range(1,4) #1,2,3 2.dics dics.get(k ...

  7. LitePal的查询

    转载:http://blog.csdn.net/guolin_blog/article/details/40153833 传统的查询数据方式 其实最传统的查询数据的方式当然是使用SQL语句了,Andr ...

  8. Python3 os.path() 模块

    os 模块提供了非常丰富的方法用来处理文件和目录.常用的方法如下表所示: 序       号 方法及描述 1 os.access(path, mode):检验权限模式 2 os.chdir(path) ...

  9. python编程基础之三十八

    正则表达式:正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑. 需要引入内置模块r ...

  10. 为什么那么多自学JAVA的后来都放弃了?总结起来就这些原因

    目前信息化产业发展势头很好,互联网就成为了很多普通人想要涉及的行业,因为相比于传统行业,互联网行业涨薪幅度大,机会也多,所以就会大批的人想要转行来学习Java开发. 目前来讲市场上需要的Java人员非 ...