`
yuanc00
  • 浏览: 29943 次
社区版块
存档分类
最新评论

Java HashSet 源代码学习

    博客分类:
  • java
 
阅读更多

 

 

注:这里使用Java 1.6版本

Set集合,是collection容器的一种;特点是保证里面的元素只出现一次。

 

1.HashSet继承AbstractSet类,实现Set、Cloneable、Serializable接口;

 

2.HashSet的内部实现。

    HashSet内部采用HashMap的方式进行实现。

 

    private transient HashMap<E,Object> map;

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

 

 

    HashSet内部采用HashMap进行实现,HashMap中的Key即是Set中的元素;value都是一样的,即上面定义的PRESENT,这是一个Object对象

 

3.HashSet的初始化

    HashSet定义了5种初始化方法:

1)Public HashSet()

    使用不带参数的HashMap的初始化方法,初始化内部的map对象;

 

2)Public HashSet(Collection<? Extends E> c)

    使用collection c进行初始化;先是使用c的元素数量初始化map,(这里使用了HashMap中的扩展因子loadFactor以及阈值的概念,同时默认最小的map大小为16,这也是和HashMap有很深的关系);然后将c中的所有元素加入map中。

 

    /**
     * Constructs a new set containing the elements in the specified
     * collection.  The <tt>HashMap</tt> is created with default load factor
     * (0.75) and an initial capacity sufficient to contain the elements in
     * the specified collection.
     *
     * @param c the collection whose elements are to be placed into this set
     * @throws NullPointerException if the specified collection is null
     */
    public HashSet(Collection<? extends E> c) {
	map = new HashMap<E,Object>(Math.max((int) (c.size()/.75f) + 1, 16));
	addAll(c);
    }

 

 

    addAll方法的实现如下:

 

    public boolean addAll(Collection<? extends E> c) {
	boolean modified = false;
	Iterator<? extends E> e = c.iterator();
	while (e.hasNext()) {
	    if (add(e.next()))
		modified = true;
	}
	return modified;
    }

 

 

    这里使用c的迭代器,将每个c中的元素加入到HashSet中;只要有一个加入成功,整个方法就算成功了。这里的addAll方法,属于AbstractCollection中定义的。

 

    public boolean add(E e) {
	return map.put(e, PRESENT)==null;
    }

 

 

    这里调用的add方法,是HashSet中定义的;加入的时候,设置key为元素e,value为定义好的Object对象PRESENT。当加入成功之后,返回true;加入失败的时候,返回false。这里的加入失败,不是因为操作真正失败了,而是因为元素e已经存在在了HashSet中

 

    这里的实现,通过HashMap实现。在HashMap中,当put一个元素的时候,返回的结果是原始的旧的结果;所以在这里,put的时候,如果元素返回结果是null,表示HashMap中不存在以e为key的元素,即元素e不在HashSet中;如果返回结果不是null,那肯定是PRESENT,表示元素e已经存在了。

 

    同时,向HashMap中put元素,为了返回旧的值;将会先查询HashMap中的结果,这里如果碰撞比较严重(大多数元素的hash结果都相同),也会有性能的问题。一般情况下,不会太严重,使用的时候注意下即可。

 

3)Public HashSet(int initialCapacity, float loadFactor)

    使用指定的参数,初始化内部map;具体见map的初始化方法。

 

4)Public HashSet(int initialCapacity)

    使用指定的参数,初始化内部map;具体见map的初始化方法。

 

5)Public HashSet(int initialCapacity, float loadFactor, Boolean dummy)

    使用指定的参数,初始化一个LinkedHashMap;

    这里的参数dummy,只是一个标识参数,没有具体的意义。

 

    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
	map = new LinkedHashMap<E,Object>(initialCapacity, loadFactor);
    }

 

 

4.迭代器(Iterator)

    HashMap中为了方便地进行元素的遍历,提供了key的迭代器、value的迭代器、Entry的迭代器;在HashSet中,因为只有key有意义,所以仅通过HashMap的key的迭代器实现了整个HashSet的迭代器。如下:

 

    /**
     * Returns an iterator over the elements in this set.  The elements
     * are returned in no particular order.
     *
     * @return an Iterator over the elements in this set
     * @see ConcurrentModificationException
     */
    public Iterator<E> iterator() {
	return map.keySet().iterator();
    }

 

 

    见注释,迭代器中的元素的顺序不是特定的。

 

5.其他基本操作

    HashSet的基本操作,包括添加add、删除remove、元素包含检查contains、清除clear、判空isEmpty等等。

    其中add方法已经在初始化的时候介绍过了;

    其他的基本操作,也都是通过HashMap实现的;基本上,都是HashMap中原方法的直接调用。

 

    public boolean isEmpty() {
	return map.isEmpty();
    }

 

 

    这里实际上就是判断,map中的size是否为0;

 

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

 

 

    使用参数o,到map中进行查询,查到表示包含;否则不包含。

 

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

 

 

    Remove和add是一对逆操作;HashMap的remove操作,返回的结果是旧的value。在这里,如果旧的结果是PRESENT,表示元素o,在HashSet中,此时返回true;否则,元素o不在HashSet中,返回false。经过这个方法之后,无论返回结果是false还是true;HashSet中都不包含元素o

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

 

    将map的元素情况,modCount清零;其他参数,loadFactor和数组长度等不变。

    public Object clone() {
	try {
	    HashSet<E> newSet = (HashSet<E>) super.clone();
	    newSet.map = (HashMap<E, Object>) map.clone();
	    return newSet;
	} catch (CloneNotSupportedException e) {
	    throw new InternalError();
	}
    }

 

    返回结果的浅拷贝(shallow copy)

 

6.最后,为了序列化,HashSet也实现了序列化和反序列化方法readObject和writeObject

 

 

分享到:
评论

相关推荐

    164个完整的Java程序源代码

    这个资源包含164个完整的Java程序源代码,这对于学习Java编程或者提升编程技能来说,是一个非常宝贵的学习材料。以下是一些基于这些源代码可能涉及的知识点的详细说明: 1. **基础语法**:源代码中会涵盖Java的基础...

    java源代码,java源代码

    Java源代码是编程世界的基石,它是Java程序员用Java语言编写的程序文本,包含了...对于压缩包中的"java源码",可能是某个具体项目或库的源代码,通过阅读和学习,我们可以深入了解其设计思路和实现方式,提升编程技能。

    JAVA开发源代码

    【JAVA开发源代码】是一个与Java编程相关的学习资源,它可能包含了从项目构思到最终实现的完整开发过程。虽然描述中提到的是一个简洁的20字概述,但我们可以深入探讨Java开发的一些关键知识点。 首先,Java是一种...

    疯狂JAVA讲义源代码光盘内容.rar

    这份压缩包"疯狂JAVA讲义源代码光盘内容.rar"包含了书中提到的所有代码示例,是学习Java编程的重要参考资料。 首先,我们来了解一下Java编程语言的基础知识。Java是一种面向对象的编程语言,由Sun Microsystems(后...

    达内java学习源代码

    "达内java学习源代码"很可能是达内教育机构提供的Java教学课程中的实践项目或示例代码集合,旨在帮助学员深入理解Java编程概念并提升实际编程技能。 达内的Java培训通常涵盖以下几个关键知识点: 1. **Java基础**...

    250个java源代码

    这些源代码实例涵盖了Java的基础概念到进阶特性,是学习和理解Java语法、编程技巧以及解决问题的有效工具。 首先,Java源代码的学习应从基础语法开始。这可能包括变量声明、数据类型(如基本类型和引用类型)、控制...

    java代码学习代码

    在"workspace"这个文件夹中,通常会包含开发项目的源代码、资源文件、配置文件等。学习过程中,可以参考这些实际代码来加深理解,通过阅读和实践来巩固Java编程技能。同时,不断实践和解决实际问题,是提升编程能力...

    JAVA,JAVA源代码,学习,计算机资料

    这个压缩包文件的主题是"JAVA,JAVA源代码,学习,计算机资料",显然它包含了一些用于学习Java编程的源代码示例。这些源代码可能涵盖了基础语法、类与对象、接口、异常处理、集合框架、多线程、输入输出流、网络编程...

    Java2源代码

    Java2源代码是Java编程语言的一个重要里程碑...通过研究这个“Java2”源代码压缩包,开发者不仅可以深化对Java语言的理解,还能学习到如何利用这些技术解决实际问题。无论是初学者还是经验丰富的开发者,都能从中受益。

    java源代码学习仓库

    Java源代码学习仓库是一个专为Java开发者准备的学习资源集合,其中包含了各种Java相关的源代码示例,涵盖了软件开发和插件实现的多个方面。通过深入研究这个仓库中的代码,开发者可以提升自己的编程技能,理解Java...

    java一些教程源代码下载

    "java一些教程源代码下载"提供了丰富的学习资源,对于初学者和进阶者都是宝贵的资料。这些源代码可以帮助读者深入理解Java语言的核心概念,提升实践能力。 1. **基础语法** Java的基础语法包括变量声明、数据类型...

    老毕java视频源代码.zip

    "老毕java视频源代码.zip" 文件很可能包含了一套完整的Java学习教程的源代码,旨在帮助初学者或进阶者理解Java编程的核心概念和实践技巧。 源代码是程序的基础,它是由程序员编写的、人可读的文本,包含了程序的...

    Java学习源代码资源

    这个"Java学习源代码资源"的压缩包显然为初学者和有经验的开发者提供了一个宝贵的实践平台,帮助他们深入理解Java编程的各个方面。让我们来详细探讨一下这个资源中可能包含的知识点以及如何利用它们进行学习。 首先...

    HashSet工作原理_动力节点Java学院整理

    对于 HashSet 而言,它是基于 HashMap 实现的,HashSet 底层采用 HashMap 来保存所有元素,因此 HashSet 的实现比较简单,查看 HashSet 的源代码,可以看到如下代码:

    250个Java实例源代码.rar

    "250个Java实例源代码.rar"这个压缩包显然包含了250个用于学习和实践Java编程的示例程序。这些实例源代码是Java初学者和进阶者提升技能、理解语言特性和最佳实践的重要资源。 1. **Java基础知识**:这些实例可能...

    java作业源代码

    "java作业源代码"这个主题通常涉及到的是初学者在学习Java基础时所完成的一些练习项目,目的是帮助他们理解和掌握Java的基本语法和编程概念。 在描述中提到的"CardGame"可能是一个基于Java编写的纸牌游戏程序。在...

    Java语言程序设计源代码

    总而言之,《Java语言程序设计》的源代码是一份宝贵的资源,它可以帮助你深入学习Java编程语言,理解其核心概念和特性,从而成为一名熟练的Java开发者。通过阅读和调试这些代码,你不仅可以巩固理论知识,还能培养...

    java大全书上源代码2

    通过阅读和实践这些源代码,你可以深入学习Java的各种特性,包括但不限于: 1. 类和对象:Java是面向对象的语言,源代码会展示如何定义类,创建对象,以及如何利用继承、封装和多态等面向对象原则来设计软件。 2. ...

    毕向东老师java全部源代码

    【标题】"毕向东老师java全部源代码"涵盖了Java编程学习的基础到进阶的大量实践案例,由知名教育专家毕向东老师编写的。这个压缩包包含的源代码是按照学习天数进行组织的,从day01到day35,每一天的代码都完整无缺,...

Global site tag (gtag.js) - Google Analytics