此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用 null 元素。
此类为基本操作提供了稳定性能,这些基本操作包括 add、remove、contains 和 size,假定哈希函数将这些元素正确地分布在桶中。对此 set 进行迭代所需的时间与 HashSet 实例的大小(元素的数量)和底层 HashMap 实例(桶的数量)的“容量”的和成比例。因此,如果迭代性能很重要,则不要将初始容量设置得太高(或将加载因子设置得太低)。
定义:public class HashSet
// HashSet 构造方法摘要
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 实例具有指定的初始容量和指定的加载因子。
基于 TreeMap
的 NavigableSet
实现。使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的 Comparator
进行排序,具体取决于使用的构造方法。
此实现为基本操作(add
、remove
和 contains
)提供受保证的 log(n) 时间开销。
注意,如果要正确实现 Set
接口,则 set 维护的顺序(无论是否提供了显式比较器)必须与 equals 一致。(关于与 equals 一致 的精确定义,请参阅 Comparable
或 Comparator
。)这是因为 Set
接口是按照 equals
操作定义的,但 TreeSet
实例使用它的 compareTo
(或 compare
)方法对所有元素进行比较,因此从 set 的观点来看,此方法认为相等的两个元素就是相等的。即使 set 的顺序与 equals 不一致,其行为也是 定义良好的;它只是违背了 Set
接口的常规协定。
定义:public class TreeSet
// TreeSet 构造方法摘要
TreeSet() // 构造一个新的空 set,该 set 根据其元素的自然顺序进行排序。
TreeSet(Collection extends E> c) // 构造一个包含指定 collection 元素的新 TreeSet,它按照其元素的自然顺序进行排序。
TreeSet(Comparator super E> comparator) // 构造一个新的空 TreeSet,它根据指定比较器进行排序。
TreeSet(SortedSet s) // 构造一个与指定有序 set 具有相同映射关系和相同排序的新 TreeSet。
// TreeSet 一些特有的方法
E ceiling(E e) // 返回此 set 中大于等于给定元素的最小元素;如果不存在这样的元素,则返回 null。
E floor(E e) // 返回此 set 中小于等于给定元素的最大元素;如果不存在这样的元素,则返回 null。
E first() // 返回此 set 中当前第一个(最低)元素。
E last() // 返回此 set 中当前最后一个(最高)元素。
E higher(E e) // 返回此 set 中严格大于给定元素的最小元素;如果不存在这样的元素,则返回 null。
E lower(E e) // 返回此 set 中严格小于给定元素的最大元素;如果不存在这样的元素,则返回 null。
E pollFirst() // 获取并移除第一个(最低)元素;如果此 set 为空,则返回 null。
E pollLast() // 获取并移除最后一个(最高)元素;如果此 set 为空,则返回 null。
Collection
|--List
|--ArrayList
|--LinkedList
|--Vector
|--set
|--HashSet
1. 底层数据结构是哈希表
2. HashSet实现不是同步的
3. HashSet通过hashCode(),equals()这两个方法保证元素的唯一性
4. 如果元素的hashCode值相同,则调用equals判断返回值是否为true
5. 如果元素的hashCode值不同,不会再调用equals进行判断
6. 对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashCode(),equals()方法
|--TreeSet
1. 底层数据结构是二叉树
2. TreeSet 实现不是同步的
3. TreeSet 保证元素惟一性的依据:CompareTo() 方法 return 0;
4. TreeSet 删除元素,判断是否包含元素都是依赖于compareTo()方法
5. 元素若想要存入TreeSet里面,要求元素有比较性。
6. TreeSet 排序的第一种实现方式:让元素具有比较性。
需要元素实现 Comparable 接口里面唯一的 compareTo() 方法,让类具有比较性。
这种方式也称为元素的自然顺序,或者叫做默认顺序。
7. TreeSet 排序的第二种实现方式:让集合具备比较性。
当元素自身不具备比较性,或者所具备的比较性不是所需的。
这时就需要让集合自身具备比较性,在初始化集合的时候,传入比较器。
8. 当两种排序方式都存在时,以比较器为主。
/*
* 第一种方式: 让类具有比较性的方式
* 通过让对象实现 Comparable 接口的方式,赋予元素比较性,让 TreeSet 利用重写的 CompareTo() 进行比较排序
*/
class Book01 implements Comparable{
private String name;
private int price;
public Book01(String name, int price) {
this.name = name;
this.price = price;
}
// 实现Comparable接口, 重写compareTo()方法,让类具备比较性
@Override
public int compareTo(Book01 o) {
int _tmp = new Integer(this.price).compareTo(new Integer(o.getPrice()));
if (_tmp == 0) {
return this.name.compareTo(o.getName());
}else {
return _tmp;
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
public class ComparableDemo {
public static void main(String[] args) {
TreeSet treeSet = new TreeSet<>();
treeSet.add(new Book01("JAVA01", 28));
treeSet.add(new Book01("JAVA02", 29));
treeSet.add(new Book01("JAVA03", 30));
treeSet.add(new Book01("JAVA01", 28));
Iterator< Book01> iterator = treeSet.iterator();
while (iterator.hasNext()) {
Book01 book = (Book01) iterator.next();
System.out.println(book.getName()+":::::"+book.getPrice());
}
}
}
/*
* 第二种的方式: 让集合具备比较能力
* 通过让 MyComparator 类实现 Comparator 接口,创建出自己的比较器类。
* 在集合初始化的时候,将自定义的比较器的匿名对象当作参数传入,让集合具备比较功能。
*/
class Book02{
private String name;
private int price;
public Book02(String name, int price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
class MyComparator implements Comparator { // 自定义的实现了比较器(Comparator)接口的类
@Override
public int compare(Book02 o1, Book02 o2) { // 实现比较器的 compare() 方法
int _tmp = new Integer(o1.getPrice()).compareTo(new Integer(o2.getPrice()));
if (_tmp == 0) {
return o1.getName().compareTo(o2.getName());
}else {
return _tmp;
}
}
}
public class ComparatorDemo{
public static void main(String[] args) {
TreeSet treeSet = new TreeSet<>(new MyComparator());
treeSet.add(new Book02("JAVA01", 28));
treeSet.add(new Book02("JAVA02", 29));
treeSet.add(new Book02("JAVA03", 30));
treeSet.add(new Book02("JAVA01", 28));
Iterator< Book02> iterator = treeSet.iterator();
while (iterator.hasNext()) {
Book02 book = (Book02) iterator.next();
System.out.println(book.getName()+":::::"+book.getPrice());
}
}
}