zoukankan      html  css  js  c++  java
  • java集合系列——Set之HashSet和TreeSet介绍(十)

    一.Set的简介
    Set是一个不包含重复元素的 collection。更确切地讲,set 不包含满足 e1.equals(e2) 的元素。对 e1 和 e2,并且最多包含一个为 null 的元素。

    Set的类关系图:

    这里写图片描述

    1.继承于Collection接口,具有增删查改的方法!

    2.AbstractCollection抽象类,实现了Collection接口,并实现了里面的一些方法,如isEmpty、contains等。

    3.Set的两个实现类,HashSet和TreeSet

    • HashSet实现本质其实就是HashMap,HashSet里面的元素是无序的。
    • TreeSet实现本质其实就是TreeSet,TreeSet里面的元素是有序的。

    二.HashSet
    1.概述
    HashSet实现Set接口,那么它也是一个不包含重复元素的一个无序的集合,允许使用null,有且仅有一个元素为null!

    HashSet也是一个非同步的方法,如果要在多个线程中使用,要注意进行同步封装!

    Set s = Collections.synchronizedSet(new HashSet(...));
    

    HashSet通过iterator()返回的迭代器是fail-fast的。

    2.继承关系和API

    HashSet API

    类 HashSet<E>
    
    java.lang.Object
      继承者 java.util.AbstractCollection<E>
          继承者 java.util.AbstractSet<E>
              继承者 java.util.HashSet<E>
    类型参数:
    E - 此 set 所维护的元素的类型
    所有已实现的接口:
    Serializable, Cloneable, Iterable<E>, Collection<E>, Set<E>
    

    LinkedHashSet继承了HashSet,实现链表的set集合。

    (1):构造方法

    HashSet() 
              构造一个新的空 set,其底层 HashMap 实例的默认初始容量是 16,加载因子是 0.75。
    HashSet(Collection<? extends E> c) 
              构造一个包含指定 collection 中的元素的新 set。
    HashSet(int initialCapacity) 
              构造一个新的空 set,其底层 HashMap 实例具有指定的初始容量和默认的加载因子(0.75)。
    HashSet(int initialCapacity, float loadFactor) 
              构造一个新的空 set,其底层 HashMap 实例具有指定的初始容量和指定的加载因子。
    

    (2)方法:

     boolean	add(E e) 
              如果此 set 中尚未包含指定元素,则添加指定元素。
     void	clear() 
              从此 set 中移除所有元素。
     Object	clone() 
              返回此 HashSet 实例的浅表副本:并没有复制这些元素本身。
     boolean	contains(Object o) 
              如果此 set 包含指定元素,则返回 true。
     boolean	isEmpty() 
              如果此 set 不包含任何元素,则返回 true。
     Iterator<E>	iterator() 
              返回对此 set 中元素进行迭代的迭代器。
     boolean	remove(Object o) 
              如果指定元素存在于此 set 中,则将其移除。
     int	size() 
              返回此 set 中的元素的数量(set 的容量)。
    

    3.总结

    HashSet中含有一个"HashMap类型的成员变量"map,HashSet的操作函数,实际上都是通过map实现的。

    有两种遍历的方式:
    (1)使用 Iterator

    第一步:根据iterator()获取HashSet的迭代器。
    第二步:遍历迭代器获取各个元素。

    for(Iterator iterator = set.iterator();
           iterator.hasNext(); ) { 
        iterator.next();
    }
    

    (2)使用foreach

    第一步:根据toArray()获取HashSet的元素集合对应的数组。
    第二步:遍历数组,获取各个元素。

    Object[] object = (String[])set.toArray();
    for (Object obj : object)
        System.out.printf(obj);
    

    三.TreeSet
    1.概述
    基于 TreeMap 的 NavigableSet 实现。使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的 Comparator进行排序,具体取决于使用的构造方法。

    2.继承关系和API

    TreeSet API
    (1)继承关系:

    类 TreeSet<E>
    
    java.lang.Object
      继承者 java.util.AbstractCollection<E>
          继承者 java.util.AbstractSet<E>
              继承者 java.util.TreeSet<E>
    类型参数:
    E - 此 set 维护的元素的类型
    所有已实现的接口:
    Serializable, Cloneable, Iterable<E>, Collection<E>, NavigableSet<E>, Set<E>, SortedSet<E>
    

    继承于AbstractSet,AbstractSet实现了equals和hashcode方法。

    实现了NavigableSet接口,意味着它支持一系列的导航方法。比如查找与指定目标最匹配项。

    实现了Cloneable接口,意味着它能被克隆。

    实现了java.io.Serializable接口,意味着它支持序列化。

    (2)构造方法:

    TreeSet() 
              构造一个新的空 set,该 set 根据其元素的自然顺序进行排序。
    TreeSet(Collection<? extends E> c) 
              构造一个包含指定 collection 元素的新 TreeSet,它按照其元素的自然顺序进行排序。
    TreeSet(Comparator<? super E> comparator) 
              构造一个新的空 TreeSet,它根据指定比较器进行排序。
    TreeSet(SortedSet<E> s) 
              构造一个与指定有序 set 具有相同映射关系和相同排序的新 TreeSet。
    

    (3)方法:

     boolean	add(E e) 
              将指定的元素添加到此 set(如果该元素尚未存在于 set 中)。
     boolean	addAll(Collection<? extends E> c) 
              将指定 collection 中的所有元素添加到此 set 中。
     E	ceiling(E e) 
              返回此 set 中大于等于给定元素的最小元素;如果不存在这样的元素,则返回 null。
     void	clear() 
              移除此 set 中的所有元素。
     Object	clone() 
              返回 TreeSet 实例的浅表副本。
     Comparator<? super E>	comparator() 
              返回对此 set 中的元素进行排序的比较器;如果此 set 使用其元素的自然顺序,则返回 null。
     boolean	contains(Object o) 
              如果此 set 包含指定的元素,则返回 true。
     Iterator<E>	descendingIterator() 
              返回在此 set 元素上按降序进行迭代的迭代器。
     NavigableSet<E>	descendingSet() 
              返回此 set 中所包含元素的逆序视图。
     E	first() 
              返回此 set 中当前第一个(最低)元素。
     E	floor(E e) 
              返回此 set 中小于等于给定元素的最大元素;如果不存在这样的元素,则返回 null。
     SortedSet<E>	headSet(E toElement) 
              返回此 set 的部分视图,其元素严格小于 toElement。
     NavigableSet<E>	headSet(E toElement, boolean inclusive) 
              返回此 set 的部分视图,其元素小于(或等于,如果 inclusive 为 true)toElement。
     E	higher(E e) 
              返回此 set 中严格大于给定元素的最小元素;如果不存在这样的元素,则返回 null。
     boolean	isEmpty() 
              如果此 set 不包含任何元素,则返回 true。
     Iterator<E>	iterator() 
              返回在此 set 中的元素上按升序进行迭代的迭代器。
     E	last() 
              返回此 set 中当前最后一个(最高)元素。
     E	lower(E e) 
              返回此 set 中严格小于给定元素的最大元素;如果不存在这样的元素,则返回 null。
     E	pollFirst() 
              获取并移除第一个(最低)元素;如果此 set 为空,则返回 null。
     E	pollLast() 
              获取并移除最后一个(最高)元素;如果此 set 为空,则返回 null。
     boolean	remove(Object o) 
              将指定的元素从 set 中移除(如果该元素存在于此 set 中)。
     int	size() 
              返回 set 中的元素数(set 的容量)。
     NavigableSet<E>	subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) 
              返回此 set 的部分视图,其元素范围从 fromElement 到 toElement。
     SortedSet<E>	subSet(E fromElement, E toElement) 
              返回此 set 的部分视图,其元素从 fromElement(包括)到 toElement(不包括)。
     SortedSet<E>	tailSet(E fromElement) 
              返回此 set 的部分视图,其元素大于等于 fromElement。
     NavigableSet<E>	tailSet(E fromElement, boolean inclusive) 
              返回此 set 的部分视图,其元素大于(或等于,如果 inclusive 为 true)fromElement。
    

    3.总结

    (1)TreeSet中不允许使用null元素!在添加的时候如果添加null,则会抛出NullPointerException异常。

    (2)TreeSet是基于TreeMap实现的。TreeSet中的元素支持2种排序方式:自然排序 或者 根据创建TreeSet 时提供的 Comparator 进行排序。这取决于使用的构造方法。

    (3)TreeSet是非同步的方法。 它的iterator 方法返回的迭代器是fail-fast的。

    (4)TreeSet不支持快速随机遍历,只能通过迭代器进行遍历!
    例子:

    a.使用Iterator顺序遍历

    for(Iterator iter = set.iterator(); iter.hasNext(); ) { 
        iter.next();
    } 
    

    b.使用foreach

    Object[] object = (Object[])set.toArray();
    for (Object obj : object)
        System.out.printf(obj);
    

    四.源码
    对TreeSet和HashSet的源码不再进行剖析,二者分别是基于TreeMap和HashMap实现的,只是对应的节点中只有key,而没有value,因此对TreeMap和HashMap比较了解的话,对TreeSet和HashSet的理解就会非常容易。

    五.总结对比(使用场景)

    1.HashSet是一个无序的集合,基于HashMap实现;TreeSet是一个有序的集合,基于TreeMap实现。

    2.HashSet集合中允许有null元素,TreeSet集合中不允许有null元素。

    3.HashSet和TreeSet都是非同步!在使用Iterator进行迭代的时候要注意fail-fast。


    欢迎访问我的csdn博客,我们一同成长!

    "不管做什么,只要坚持下去就会看到不一样!在路上,不卑不亢!"

    博客首页http://blog.csdn.net/u010648555

  • 相关阅读:
    Java时间和时间戳的相互转换
    linux 通过pid 寻找程序路径的最简单命令(pwdx)
    Oracle--存储过程学习进阶
    经典sql总结(2)
    经典sql总结(1)
    类的初始化
    StringBuffer和String 的例子
    i=i++
    一个异常学习的好例子
    有空研究这篇http://blog.csdn.net/studyvcmfc/article/details/7720258 研究后写篇记录
  • 原文地址:https://www.cnblogs.com/aflyun/p/6509322.html
Copyright © 2011-2022 走看看