之前我写过的一片博文讲过了散列表(Hash Table),而散列表可以用来实现散列集(HashSet)和散列映射表(HashMap)。
HashSet
HashSet<T>类有四种构造函数:
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. 它的全部方法:
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](file:///D:/jdk1.7/docs/api/java/util/TreeSet.html "type parameter in TreeSet")
> comparator)
,只要传递一个Comparator对象给TreeSet集就可以。
例如:
“`java
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方法。
“`java
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。