HashSet和TreeSet区别
HashSet和TreeSet区别
import java.util.HashSet;
import java.util.Iterator;
import java.util.TreeSet;
public class SetTest {
/**
* @param args
*/
public static void main(String[] args) {
// TODO 自动生成方法存根
HashSet ht = new HashSet();
ht.add("A");
ht.add("D");
ht.add("C");
ht.add("B");
ht.add("T");
//ht.add(null);//去掉注释运行,可以运行
TreeSet ts = new TreeSet();
//ts.add(null);//去掉注释运行,不可以运行
ts.add("A");
ts.add("E");
ts.add("B");
ts.add("C");
ts.add("W");
Iterator it = ht.iterator();
while(it.hasNext()){
System.out.println("========"+it.next());;
}
Iterator ti = ts.iterator();
while(ti.hasNext()){
System.out.println(">>>>>>>."+ti.next());;
}
}
}
运行可以看出明显,1、Treeset中的数据是自动排好序的,不允许放入null值
2、HashSet中的数据是无序的,可以放入null,但只能放入一个null,两者中的值都不能重复,就如数据库中唯一约束
3、HashSet要求放入的对象必须实现HashCode()方法,放入的对象,是以hashcode码作为标识的,而具有相同内容的String对象,hashcode是一样,所以放入的内容不能重复。而同一个类的对象可以放入不同的实例,但是如果想按指定的对象属性来判断是否为相同对象的话,可以自己重写hashCode()方法来实现,例如:
public int hashCode() {
return this.age;
}
这就是表示我这里要求年龄相同的就为同一个人
又如:
(//这表示具有相同用户名的实例,在这认为是同一个对象。即按username唯一约束
public int hashCode() {
return this.username.hashCode();
}
4.另外,Treeset要放入对象的话 ,需要实现Compareable接口及其方法,指定可以排序的方式,否则会放入失败:
public class Person implements Comparable {
private String username;
private int age;
public Person(String username,int age) {
this.username = username;
this.age = age;
}
public Person() {
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
/**
* 必须实现此方法 即使用当前对象和参数对象的年龄比较,大于的返回1,小于的返回-1,等于的返回0
* 这里使用按年龄排序
*/
public int compareTo(Object o) {
// TODO Auto-generated method stub
Person p = (Person)o;
System.out.println(this.age+"=========="+p.age);
return this.age>p.age?1:(this.age<p.age?-1:0);
}
}
===========================================================================================================
我们可以也可以构造TreeSet对象的时候,传递一个实现了Comparator接口的比较器对象,让集合里面的对象按照比较器进行排序
package collection;
import java.util.Comparator;
public class Student
{
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Student(int id, String name, String sex) {
super();
this.id = id;
this.name = name;
this.sex = sex;
}
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name){
this.name=name;
}
public Student(String name,int id){
this.id=id;
this.name=name;
}
static class MyComparator implements Comparator//这就是自己定义的比较器
{//静态内部类
public int compare(Object o1, Object o2) {
// TODO Auto-generated method stub
Student s1=(Student)o1;
Student s2=(Student)o2;
int result=s1.id>s2.id?1:(s1.id==s2.id?0:-1);
if(result==0){
result=s1.name.compareTo(s2.name);
}
return result;
}
}
}
在使用的时候:
package collection;
import java.util.Iterator;
import java.util.TreeSet;
public class TreeSetSample {
public static void main(String[]args){
TreeSet set=new TreeSet(new Student.MyComparator());//构建一个使用自定义比较器的TreeSet对象
set.add(new Student("xu",20));
set.add(new Student("zhan",3));
Iterator it=set.iterator();
while(it.hasNext()){
System.out.println(((Student)it.next()).getName());
}
System.out.println(set.last());
}
}
这样输出的是有顺序的,而且是按照MyComparator比较器进行比较的
最后 强调:
底层来说,HashSet是用Hash表来存储数据,而TreeSet是用二叉平衡树来存储数据。
功能上来说,由于TreeSet实现了SortedSet接口,所以是一个有序的Set,可以使用SortedSet接口的first()、last()等方法。
但由于要排序,势必要影响速度,所以,如果不需要顺序的话,还是使用Hash