HashSet与TreeSet的区别

浅浅的花香味﹌ 2022-08-24 00:55 304阅读 0赞

CenterHashSet与TreeSet的区别:
HashSet是基于hash算法实现的,性能优于TreeSet。通常使用HashSet,在我们需要对其中元素排序的时候才使用TreeSet。

HashSet中的元素没有顺序,但是具有集合的唯一性,即元素不可重复!

TreeSet是一个有序集合,她的元素 按照升序排列,默认是按照自然顺序排列,也就是说TreeSet中的对象元素需要实现Comparable接口。

相同点:
TreeSet类中跟HashSet类一样也没有get()方法来获取列表中的元素,所以也只能通过迭代器方法来获取。

[java] view plain copy

  1. // List set = new ArrayList(); //有序 不唯一
  2. // Set set = new HashSet(); //无序 唯一
  3. Set set = new TreeSet(); //有序 唯一

[java] view plain copy

  1. set.add(“a”);
  2. set.add(“a”);
  3. set.add(“b”);
  4. set.add(“c”);
  5. Iterator it = set.iterator();
  6. while(it.hasNext()){
  7. System.out.println(it.next());
  8. }

上面的例子可以区分三种的是否有序性。

下面的问题是转载网友的,分享学习!

============================================================

一. 问题

  1. HashSet,TreeSet是如何使用hashCode()和equal()方法的

  2. TreeMap,TreeSet中的对象何时以及为何要实现Comparable接口?

二. 回答:

  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

d. 覆写key的hashCode()和equal()时一定要注意,不要把它们和可变属性关联上, 否则属性变了之后hashCode会变,equal也会为false, 这样在Map中就找不不到它了 而且这样的对象因为找不到它所以得不到释放,这样就变成了一个无效引用了(相当于内存泄漏).

  1. 由于TreeMap需要排序,所以需要一个Comparator为键值进行大小比较.当然也是用Comparator定位的.

a. Comparator可以在创建TreeMap时指定,这时排序时使用Comparator.compare

b. 如果创建时没有指定Comparator,那么就会使用key.compareTo()方法,这就要求key必须实现Comparable接口.

c. TreeMap是使用Tree数据结构实现的,所以使用compare接口就可以完成定位了.

TreeSet是依靠TreeMap来实现的
TreeSet是一个有序集合,她的元素 按照升序排列,默认是按照自然顺序排列,也就是说TreeSet中的对象元素需要实现Comparable接口。
TreeSet类中跟HashSet类一样也没有get()方法来获取列表中的元素,所以也只能通过迭代器方法来获取。

[java] view plain copy

  1. import java.util.*;
  2. public class TreeSetTest
  3. {
  4. public static void main(String[] args)
  5. {
  6. TreeSet tr =new TreeSet();
  7. tr.add(“zhangshan”);
  8. tr.add(“wangwu”);
  9. tr.add(“lisi”);
  10. Iterator it =tr.iterator();
  11. while(it.hasNext())
  12. {
  13. System.out.println(it.next());
  14. }
  15. }
  16. }

上面打印结果为:lisi wangwu zhangshan 这时因为TreeSet是一个有序并且默认按自然顺序排列,而不像哈希表那样毫无规律。
上面向TreeSet中添加的对象好像没有实现Comparable接口哦??那是因为添加的是String对象,而String类已经实现了Comparable接口。
当然,你也可以在创建TreeSet对象时传递一个比较器来实现你自己的排序方式:
import java.util.*;
public class TreeSetTest
{
public static void main(String[] args)
{
//传递一个比较器来实现你自己的排序方式
TreeSet tr =new TreeSet(new Student.StudentComparator());
tr.add(new Student(3,”wnagwu”));
tr.add(new Student(2,”zhangshan”));
tr.add(new Student(2,”lisi”));
tr.add(new Student(1,”xiejin”));
Iterator it =tr.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
}
}

//TreeSet中的对象元素需要实现Comparable接口
class Student implements Comparable,Comparator
{
int num;
String name;
Student(int num,String name)
{
this.num=num;
this.name=name;
}
public int compareTo(Object o)
{
Student st =(Student)o;
int result;
result= num>st.num?1:(num==st.num?0:-1);
//如果学号相等,就按姓名排列
/*if(result==0)
{
return name.compareTo(st.name);
}*/
return result;
}
//实现Comparator接口并实现它的抽象方法
public int compare(Object o1,Object o2)
{
Student st1 =(Student)o1;
Student st2 =(Student)o2;
return st1.name.compareTo(st2.name);

  1. \}
  2. //重写toString()方法,因为如果不重写,打印出来的是16进制代码
  3. public String toString()
  4. \{
  5. return "num="+num+"; name="+name;
  6. \}
  7. public static class StudentComparator implements Comparator
  8. \{
  9. public int compare(Object o1,Object o2)
  10. \{
  11. Student st1 =(Student)o1;
  12. Student st2 =(Student)o2;
  13. int result;
  14. result=st1.num>st2.num?1:(st1.num==st2.num?0:-1);
  15. if(result==0)//如果学号相等 就进行名字排序
  16. \{
  17. result=st1.name.compareTo(st2.name);
  18. \}
  19. return result;
  20. \}
  21. \}

}
上面如果只使用学号排序,那么学号相同的就不会被打印的。

发表评论

表情:
评论列表 (有 0 条评论,304人围观)

还没有评论,来说两句吧...

相关阅读

    相关 HashSetTreeSet

    HashSet与TreeSet 一、HashSet特点以及存储自定义对象保证元素唯一性 1,HashSet存储字符串并遍历  Java Code  <tab