HashSet HashTable 与 TreeSet
HashSet<T>类主要是设计用来做高性能集运算的,例如对两个集合求交集、并集、差集等。集合中包含一组不重复出现且无特性顺序的元素。
HashSet<T>的一些特性如下:
1、HashSet<T>中的值不能重复且没有顺序。
2、HashSet<T>的容量会按需自动添加。
构造方法:
HashSet() 默认相等比较器创建一个空的新实例。
HashSet(IEnumerable<T> collection) 把指定集合中的collection中的数据复制到集中
HashSet(IEqualityComparer<T> comparer) 使用指定的相等比较器创建一个空的新实例
HashSet(IEnumerable<T> collection,IEqualityComparer<T> comparer) 使用指定的比较器实例化数据,且将指定集合中的元素复制到集合中。
因为HashSet<T>是专门设计来做集合运算的,因此它提供的方法中有不少是和集合运算相关的。
以下给出它的一些常用方法介绍
成员 类型 说明
Add 方法 将指定的元素添加到集合中
Clear 方法 清空集合中的所有元素
Contains 方法 确定某元素是否在HashSet<T>中
Exists 方法 确定HashSet<T>是否包含于指定条件相匹配的元素
ExceptWith 方法 从当前HashSet<T>移除指定集合中的所有元素
IntersectWith 方法 修改当前的HashSet<T>对象,以仅包含该对象和指定集合中存在的元素
IsProperSubsetOf 方法 确定HashSet<T>对象是否为指定集合的真子集
IsProperSupersetOf 方法 确定HashSet<T>对象是否为指定集合的真超集
IsSunsetOf 方法 确定HashSet<T>对象是否为指定集合的子集
IsSupersetOf 方法 确定HashSet<T>对象是否为指定集合的超集
Remove 方法 从HashSet<T>对象中移除指定的元素
RemoveWhere 方法 从HashSet<T>集合中移除与指定谓词所定义的条件相匹配的所有元素
SetEquals 方法 确定HashSet<T>对象与指定的集合中是否包含相同的元素
SynmmetricExceptWith 方法 修改当前的HashSet<T>对象,以仅包含该对象或指定集合中存在的元素
TrimExcess 方法 将HashSet<T>对象的容量设置为它所包含的元素的实际个数,向上舍入为接近的特性与实现的值。
UnionWith 方法 修改当前的HashSet<T>对象,以包含该对象本身和指定集合中存在的所有元素
TreeSet
TreeSet是依靠TreeMap来实现的。
TreeSet是一个有序集合,TreeSet中的元素将按照升序排列,缺省是按照自然排序进行排列,意味着TreeSet中的元素要实现Comparable接口。或者有一个自定义的比较器。
我们可以在构造TreeSet对象时,传递实现Comparator接口的比较器对象。
TreeSet与HashSet的区别
1. HashSet是通过HashMap实现的,TreeSet是通过TreeMap实现的,只不过Set用的只是Map的key
2. Map的key和Set都有一个共同的特性就是集合的唯一性.TreeMap更是多了一个排序的功能.
3. hashCode和equal()是HashMap用的, 因为无需排序所以只需要关注定位和唯一性即可.
a. hashCode是用来计算hash值的,hash值是用来确定hash表索引的.
b. hash表中的一个索引处存放的是一张链表, 所以还要通过equal方法循环比较链上的每一个对象 才可以真正定位到键值对应的Entry.
c. put时,如果hash表中没定位到,就在链表前加一个Entry,如果定位到了,则更换Entry中的value,并返回旧value
4. 由于TreeMap需要排序,所以需要一个Comparator为键值进行大小比较.当然也是用Comparator定位的.
a. Comparator可以在创建TreeMap时指定
b. 如果创建时没有确定,那么就会使用key.compareTo()方法,这就要求key必须实现Comparable接口.
c. TreeMap是使用Tree数据结构实现的,所以使用compare接口就可以完成定位了.
HashTable
Hashtables(哈希表)在计算机领域中已不 是一个新概念了。它们是用来加快计算机的处理速度的,用当今的标准来处理,速度非常慢,而它们可以让你在查询许多数据条目时,很快地找到一个特殊的条目。 尽管现代的机器速度已快了几千倍,但是为了得到应用程序的最佳性能,hashtables仍然是个很有用的方法。
Hashtable和HashMap对象可以让你把一个key和一个value结合起来,并用put() 方法把这对key/value输入到表中。然后你可以通过调用get()方法,把key作为参数来得到这个value(值)。只要满足两个基本的要求, key和value可以是任何对象。注意,因为key和value必须是对象,所以原始类型(primitive types)必须通过运用诸如Integer(int)的方法转换成对象。
为了将一个特定类的对象用做一个key,这个类必须提供两个方法,equals() 和 hashCode()。这两个方法在java.lang.Object中,所以所有的类都可以继承这两个方法;但是,这两个方法在Object类中的实现一般没什么用,所以你通常需要自己重载这两个方法。
Equals ()方法把它的对象同另一个对象进行比较,如果这两个对象代表相同的信息,则返回true。该方法也查看并确保这两个对象属于相同的类。如果两个参照对象 是完全一样的对象,Object.equals()返回true,这就说明了为什么这个方法通常不是很适合的原因。在大多数情况下,你需要一个方法来一个 字段一个字段地进行比较,所以我们认为代表相同数据的不同对象是相等的。
HashCode()方法通过运用对象的内容执行一个哈希函数来生成一个int值。Hashtable和HashMap用这个值来算出一对key/value位于哪个bucket(哈希元)(或列表)中。Hashtable性能
影响hashtable功效的主要因素就是表中列表的平均长度,因为平均搜索时间与这个平均长度直接相关。很显然, 要减小平均长度,你必须增加hashtable中列表的数量;如果列表数量非常大,以至于大多数列表或所有列表只包含一条记录,你就会获得最佳的搜索效 率。然而,这样做可能太过分了。如果你的hashtable的列表数远远多于数据条目,那你就没有必要做这样的内存花费了,而在一些情况下,人们也不可能 接受这样的做法。
ashtable和HashMap
Hashtable和HashMap类有三个重要的不同之处。第一个不同主要是历史原因。Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现。
也许最重要的不同是Hashtable的方法是同步的,而HashMap的方法不是。这就意味着,虽然你可以不用采取任何特殊的行为就可以在一个多 线程的应用程序中用一个Hashtable,但你必须同样地为一个HashMap提供外同步。一个方便的方法就是利用Collections类的静态的 synchronizedMap()方法,它创建一个线程安全的Map对象,并把它作为一个封装的对象来返回。这个对象的方法可以让你同步访问潜在的HashMap。这么做的结果就是当你不需要同步时,你不能切断Hashtable中的同步(比如在一个单线程的应用程序中),而且同步增加了很多处理费用。
第三点不同是,只有HashMap可以让你将空值作为一个表的条目的key或value。HashMap中只有一条记录可以是一个空的key,但任 意数量的条目可以是空的value。这就是说,如果在表中没有发现搜索键,或者如果发现了搜索键,但它是一个空的值,那么get()将返回null。如果 有必要,用containKey()方法来区别这两种情况。