0

0

Java集合类源码之Set的具体分析

黄舟

黄舟

发布时间:2017-10-10 10:16:51

|

1800人浏览过

|

来源于php中文网

原创

下面小编就为大家带来一篇java集合类源码分析之set详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

Set集合与List一样,都是继承自Collection接口,常用的实现类有HashSet和TreeSet。值得注意的是,HashSet是通过HashMap来实现的而TreeSet是通过TreeMap来实现的,所以HashSet和TreeSet都没有自己的数据结构,具体可以归纳如下:

•Set集合中的元素不能重复,即元素唯一

•HashSet按元素的哈希值存储,所以是无序的,并且最多允许一个null对象

•TreeSet按元素的大小存储,所以是有序的,并且不允许null对象

立即学习Java免费学习笔记(深入)”;

•Set集合没有get方法,所以只能通过迭代器(Iterator)来遍历元素,不能随机访问

1.HashSet

下面给出HashSet的部分源码,以理解它的实现方式。


static final long serialVersionUID = -5024744406713321676L;

 private transient HashMap map;

 // Dummy value to associate with an Object in the backing Map
 private static final Object PRESENT = new Object();

观察源码,我们知道HashSet的数据是存储在HashMap的实例对象map中的,并且对应于map中的key,而Object类型的引用PRESENT则是对应于map中的value的一个虚拟值,没有实际意义。联想到HashMap的一些特性:无序存储、key值唯一等等,我们就可以很自然地理解Set集合元素不能重复以及HashSet无序存储的特性了。

下面从源代码的角度来理解HashSet的基本用法:

•构造器(四种)

1.HashSet() 空的构造器,初始化一个空的HashMap

2.HashSet(Collection extends E> c) 传入一个子集c,用于初始化HashMap

3.HashSet(int initialCapacity, float loadFactor) 初始化一个空的HashMap,并指定初始容量和加载因子

4.HashSet(int initialCapacity) 初始化一个空的HashMap,并指定初始容量


public HashSet() {
  map = new HashMap<>();
 }

 public HashSet(Collection c) {
  map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
  addAll(c);
 }

 public HashSet(int initialCapacity, float loadFactor) {
  map = new HashMap<>(initialCapacity, loadFactor);
 }

 public HashSet(int initialCapacity) {
  map = new HashMap<>(initialCapacity);
 }

•插入元素

1.add(E e) 插入指定元素(调用HashMap的put方法实现)


   Set hashSet = new HashSet();
   hashSet.add("D");
   hashSet.add("B");
   hashSet.add("C");
   hashSet.add("A");

•查找元素

1.contains(Object o) 判断集合中是否包含指定的元素(调用HashMap的containsKey方法实现)


  public boolean contains(Object o) {
   return map.containsKey(o);
  }

2.由于HashSet的实现类中没有get方法,所以只能通过迭代器依次遍历,而不能随机访问(调用HashMap中keySet的迭代器实现)


  public Iterator iterator() {
   return map.keySet().iterator();
  }

应用示例:


Set hashSet = new HashSet();
  hashSet.add("D");
  hashSet.add("B");
  hashSet.add("C");
  hashSet.add("A");
  for (Iterator iterator = hashSet.iterator(); iterator.hasNext();) {
   String string = (String) iterator.next();
   System.out.print(string+" ");
  }//D A B C

•修改元素

由于HashMap中的key值不能修改,所以HashSet不能进行修改元素的操作

•删除元素

1.remove(Object o) 删除指定元素(调用HashMap中的remove方法实现,返回值为true或者false)

Transor
Transor

专业的AI翻译工具,支持网页、字幕、PDF、图片实时翻译

下载


  public boolean remove(Object o) {
   return map.remove(o)==PRESENT;
  }

2.clear() 清空元素(调用HashMap中的clear方法实现,没有返回值)


public void clear() {
   map.clear();
  }

2.TreeSet

TreeSet是SortedSet接口的唯一实现类。前面说过,TreeSet没有自己的数据结构而是通过TreeMap实现的,所以TreeSet也是基于红黑二叉树的一种存储结构,所以TreeSet不允许null对象,并且是有序存储的(默认升序)。


private transient NavigableMap m;
 
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();

上述源代码中的NavigableMap是继承自SrotedMap的一个接口,其实现类为TreeMap,因此TreeSet中的数据是通过TreeMap来存储的,此处的PRESENT也是没有实际意义的虚拟值。

下面从源代码的角度来理解HashSet的基本用法:

•构造器(四种)

1.TreeSet() 空的构造器,初始化一个空的TreeMap,默认升序排列

2.TreeSet(Comparator super E> comparator) 传入一个自定义的比较器,常常用于实现降序排列

3.TreeSet(Collection extends E> c) 传入一个子集c,用于初始化TreeMap对象,默认升序

4.TreeSet(SortedSet s) 传入一个有序的子集s,用于初始化TreeMap对象,采用子集的比较器


public TreeSet() {
  this(new TreeMap());
 }

 public TreeSet(Comparator comparator) {
  this(new TreeMap<>(comparator));
 }

 public TreeSet(Collection c) {
  this();
  addAll(c);
 }

 public TreeSet(SortedSet s) {
  this(s.comparator());
  addAll(s);
 }

应用示例


//自定义一个比较器,实现降序排列
  Set treeSet = new TreeSet(new Comparator() {

   @Override
   public int compare(Integer o1, Integer o2) {
//    return 0;  //默认升序
    return o2.compareTo(o1);//降序
   }
  });
  treeSet.add(200);
  treeSet.add(120);
  treeSet.add(150);
  treeSet.add(110);
  for (Iterator iterator = treeSet.iterator(); iterator.hasNext();) {
   Integer integer = (Integer) iterator.next();
   System.out.print(integer+" ");
  } //200 150 120 110


ArrayList list = new ArrayList();
  list.add(300);
  list.add(120);
  list.add(100);
  list.add(150);
  System.out.println(list); //[300, 120, 100, 150]
  
  //传入一个子集,默认升序排列
  TreeSet treeSet = new TreeSet(list);
  for (Iterator iterator = treeSet.iterator(); iterator.hasNext();) {
   Integer integer = (Integer) iterator.next();
   System.out.print(integer+" ");
  }//100 120 150 300


/*
   * 传入一个有序的子集,采用子集的比较器
   *  注意子集的类型必须是SortedSet及其子类或者实现类,否则将采用默认的比较器
   *  所以此处subSet的类型也可以是TreeSet。
   */
  
  SortedSet subSet = new TreeSet(new Comparator() {

   @Override
   public int compare(Integer o1, Integer o2) {
//    return 0;  //默认升序
    return o2.compareTo(o1);//降序
   }
  });
  subSet.add(200);
  subSet.add(120);
  subSet.add(150);
  subSet.add(110);
  for (Iterator iterator = subSet.iterator(); iterator.hasNext();) {
   Integer integer = (Integer) iterator.next();
   System.out.print(integer+" ");
  } //200 150 120 110 
  
  System.out.println();
  Set treeSet = new TreeSet(subSet);
  for (Iterator iterator = treeSet.iterator(); iterator.hasNext();) {
   Integer integer = (Integer) iterator.next();
   System.out.print(integer+" ");
  }//200 150 120 110 
  
  System.out.println();
  treeSet.add(500);
  treeSet.add(100);
  treeSet.add(105);
  for (Iterator iterator = treeSet.iterator(); iterator.hasNext();) {
   Integer integer = (Integer) iterator.next();
   System.out.print(integer+" ");
  }//500 200 150 120 110 105 100

• 插入元素

1.add(E e) 插入指定的元素(调用TreeMap的put方法实现)

2.addAll(Collection extends E> c) 插入一个子集c


ArrayList list = new ArrayList();
  list.add(300);
  list.add(120);
  list.add(100);
  list.add(150);
  System.out.println(list); //[300, 120, 100, 150]
  
  Set treeSet = new TreeSet();
  
  //插入一个子集,默认升序
  treeSet.addAll(list);
  for (Iterator iterator = treeSet.iterator(); iterator.hasNext();) {
   Integer integer = (Integer) iterator.next();
   System.out.print(integer+" ");
  }//100 120 150 300

•查找元素

1.contains(Object o) 判断集合中是否包含指定对象(调用TreeMap的containsKey方法实现)

2.与HashSet一样,TreeSet的实现类中没有get方法,所以只能通过迭代器依次遍历,而不能随机访问(调用TreeMap中keySet的迭代器实现)。

•修改元素

TreeSet不能进行修改元素的操作,原因与HashSet一样。

•删除元素

1.remove(Object o) 删除指定元素(调用TreeMap中的remove方法实现,返回true或者false)


  public boolean remove(Object o) {
   return m.remove(o)==PRESENT;
  }

2.clear() 清空元素(调用TreeMap中的clear方法实现,无返回值)


  public void clear() {
   m.clear();
  }

应用示例:


ArrayList list = new ArrayList();
  list.add(300);
  list.add(120);
  list.add(100);
  list.add(150);
  System.out.println(list); //[300, 120, 100, 150]
  
  Set treeSet = new TreeSet();
  
  //插入一个子集,默认升序
  treeSet.addAll(list);
  for (Iterator iterator = treeSet.iterator(); iterator.hasNext();) {
   Integer integer = (Integer) iterator.next();
   System.out.print(integer+" ");
  }//100 120 150 300 
  
  System.out.println(treeSet.remove(100));//true
  for (Iterator iterator = treeSet.iterator(); iterator.hasNext();) {
   Integer integer = (Integer) iterator.next();
   System.out.print(integer+" ");
  }//120 150 300 
  
  treeSet.clear();
  System.out.println(treeSet.size());//0

至此,HashSet和TreeSet的存储结构及基本用法介绍完毕。

相关文章

java速学教程(入门到精通)
java速学教程(入门到精通)

java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

4

2026.01.16

全民K歌得高分教程大全
全民K歌得高分教程大全

本专题整合了全民K歌得高分技巧汇总,阅读专题下面的文章了解更多详细内容。

3

2026.01.16

C++ 单元测试与代码质量保障
C++ 单元测试与代码质量保障

本专题系统讲解 C++ 在单元测试与代码质量保障方面的实战方法,包括测试驱动开发理念、Google Test/Google Mock 的使用、测试用例设计、边界条件验证、持续集成中的自动化测试流程,以及常见代码质量问题的发现与修复。通过工程化示例,帮助开发者建立 可测试、可维护、高质量的 C++ 项目体系。

10

2026.01.16

java数据库连接教程大全
java数据库连接教程大全

本专题整合了java数据库连接相关教程,阅读专题下面的文章了解更多详细内容。

33

2026.01.15

Java音频处理教程汇总
Java音频处理教程汇总

本专题整合了java音频处理教程大全,阅读专题下面的文章了解更多详细内容。

15

2026.01.15

windows查看wifi密码教程大全
windows查看wifi密码教程大全

本专题整合了windows查看wifi密码教程大全,阅读专题下面的文章了解更多详细内容。

42

2026.01.15

浏览器缓存清理方法汇总
浏览器缓存清理方法汇总

本专题整合了浏览器缓存清理教程汇总,阅读专题下面的文章了解更多详细内容。

7

2026.01.15

ps图片相关教程汇总
ps图片相关教程汇总

本专题整合了ps图片设置相关教程合集,阅读专题下面的文章了解更多详细内容。

9

2026.01.15

ppt一键生成相关合集
ppt一键生成相关合集

本专题整合了ppt一键生成相关教程汇总,阅读专题下面的的文章了解更多详细内容。

6

2026.01.15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 2.6万人学习

C# 教程
C# 教程

共94课时 | 6.8万人学习

Java 教程
Java 教程

共578课时 | 46.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号