之前我写过的一片博文讲过了散列表(Hash Table),而散列表可以用来实现散列集(HashSet)和散列映射表(HashMap)。
HashSet
HashSet<T>类有四种构造函数:
Constructor and Description |
---|
HashSet()
Constructs a new, empty set; the backing
HashMap instance has default initial capacity (16) and load factor (0.75).
|
HashSet(Collection<? extends E> c)
Constructs a new set containing the elements in the specified collection.
|
HashSet(int initialCapacity)
Constructs a new, empty set; the backing
HashMap instance has the specified initial capacity and default load factor (0.75).
|
HashSet(int initialCapacity, float loadFactor)
Constructs a new, empty set; the backing
HashMap instance has the specified initial capacity and the specified load factor.
|
Modifier and Type | Method and Description |
---|---|
boolean | add(E e)
Adds the specified element to this set if it is not already present.
|
void | clear()
Removes all of the elements from this set.
|
Object | clone()
Returns a shallow copy of this
HashSet instance: the elements themselves are not cloned.
|
boolean | contains(Object o)
Returns
true if this set contains the specified element.
|
boolean | isEmpty()
Returns
true if this set contains no elements.
|
Iterator<E> | iterator()
Returns an iterator over the elements in this set.
|
boolean | remove(Object o)
Removes the specified element from this set if it is present.
|
int | size()
Returns the number of elements in this set (its cardinality).
|
TreeSet
TreeSet为树集,,是一个有序的集合( an sorted collection)。这个类按某个顺序进行排序,实现用的是红黑树。
构造函数:
TreeSet()
Constructs a new, empty tree set, sorted according to the natural ordering of its elements.
|
TreeSet(Collection<? extends E> c)
Constructs a new tree set containing the elements in the specified collection, sorted according to the
natural ordering of its elements.
|
TreeSet(Comparator<? super E> comparator)
Constructs a new, empty tree set, sorted according to the specified comparator.
|
TreeSet(SortedSet<E> s)
Constructs a new tree set containing the same elements and using the same ordering as the specified sorted set.
|
这里排序有两种实现方法:
1.实现Comparable接口
默认情况下,TreeSet假定插入的元素实现了Comparable接口。这个接口定义了一个方法:
public interface Comparable<T>{
int comparTo(T other);
}
例如String类,如果a与b相等,a.comparTo(b)返回0;如果a>b,返回正值。
但是这种方法有个缺点,就是一个类只能使用一种排序的方法,例如Employee类既想用id进行排序,也想用salary进行排序,肿么办?这就要用第二种方法。
2.实现Comparator接口
注意到构造函数TreeSet(Comparator<? super E> comparator),只要传递一个Comparator对象给TreeSet集就可以。
例如:
Set<Employee> otherStaff = new TreeSet<Employee>(
new Comparator<Employee>(){
public int compare(Employee a, Employee b){
return (int)(a.getSalary() - b.getSalary()); //根据salsay的大小排序
}
}
);
测试程序
HashSet和TreeSet的测试程序:
这里重写了hashCode方法和equals方法。
package com.xujin;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
public class LinkedListTest{
public static void main(String...arg){
Employee jim = new Employee("Jim", 8000);
Employee bob = new Employee("Bob", 9000);
Manager jin = new Manager("Gin", 10000, 4000);
/*********HashSet类测试************************************/
Set<Employee> staff = new HashSet<Employee>();
staff.add(jim);
staff.add(bob);
staff.add(jin);
staff.add(bob);//HashCode相同,拒绝添加
System.out.println(staff.size());//3
Iterator<Employee> iter = staff.iterator();
while(iter.hasNext()){
Employee e = iter.next();
System.out.println(e);
}
/*********TreeSet类测试************************************/
Set<Employee> otherStaff = new TreeSet<Employee>(
new Comparator<Employee>(){
public int compare(Employee a, Employee b){
return (int)(a.getSalary() - b.getSalary()); //根据salsay的大小排序
}
}
);
otherStaff.add(bob);
otherStaff.add(jim);
System.out.println(otherStaff);//[id:1 name:Jim salary:8000.0, id:2 name:Bob salary:9000.0]
}
}
class Employee{
public Employee(String name){
this.name = name;
id = nextId;
nextId++;
}
public String toString(){
return "id:" + id + " name:" + name +" salary:" + salary;
}
public int hashCode(){
return id;
}
public boolean equals(Employee e){
if(id - e.getId() == 0)return true;
return false;
}
public Employee(String name, double salary){
this(name);//调用另一构造器
this.salary = salary;
}
//定义访问器方法
public final String getName(){
return name;
}
public double getSalary(){
return salary;
}
public final int getId(){
return id;
}
//定义更改器方法
public final void setName(String name){
this.name = name;
}
public final void setSalary(double salary){
this.salary = salary;
}
public final void raiseSalary(double percent){
this.salary *= (1 + percent);
}
//定义变量
private String name = "";//实例域初始化
private double salary;
private int id;
private static int nextId = 1;
}
class Manager extends Employee{
public Manager(String name, double salary, double bonus){
super(name, salary);//super在构造器中的使用,可以调用超类的构造器
setBonus(bonus);
}
public String toString(){
return super.toString() + ",bonus:" + bonus;
}
public double getBonus(){
return bonus;
}
//重写getSalary方法
public double getSalary(){
double baseSalary = super.getSalary();//调用了超类的getSalary方法
return baseSalary + bonus;
}
public void setBonus(double bonus){
this.bonus = bonus;
}
private double bonus;
}
使用策略
HashSet和TreeSet
HashSet在速度上略胜一筹,以为她不需要排序。
如果不需要实现排序,就大可不必用TreeSet。