java学习笔记<十四>set集合

<一>HashSet类

HashSet按照Hash算法来存储集合中的元素,因此有很好的存取和查找性能

HashSet具有以下特点

1.不能保证元素的排列顺序,顺序可能与添加顺序不同

2.集合元素可以是null值

3.HashSet不是同步的,如果多线程同时访问一个 HashSet,假设有两个或者两个以上线程同修改了HashSet集合时,则必须通过代码来保证其同步

向HashSet存入一个对象时,它会调用该对象的hashCode()来得到该对象的hashCode值,然后根据hashCode值来确定该对象在HashSet中存储的位置,如果有两个元素通过equals()方法比较后返回true,但是这两个对象的hashCode值不同,HashSet依然把他们存储在不同的位置,添加成功

一句话说就是HashSet判断两个对象是否相等是通过equals()方法返回true,并且两个对象hashCode值相等

LinkedHashSet类

LinkedHashSet类是HashSet类的子类,它也是根据元素的hashCode值来决定元素的存储位置,但它同时使用链表维护元素的次序,当遍历LinkedHashSet集合里的元素时,LinkHashSet将会按元素的添加顺序来访问集合里的元素,输出LinkHashSet集合的元素时,元素的顺序总是与添加顺序一致

<二>TreeSet类

TreeSet可以确保集合元素处于排序状态,与HashSet集合采用hash算法来决定元素的存储位置不同,TreeSet采用红黑树的数据结构来存储集合元素

TreeSet类还额外提供几个方法

Object first();  //返回集合的第一个元素

Object last(); //返回集合的最后一个元素

Object lower(Object e);//  返回位于指定元素之前的元素

Object higher(Object d);//返回位于指定元素之后的元素

SortedSet subSet(ObjectfromElement,ObjecttoElement);返回此set的子集合,范围从fromElement到toElement

SortedSet headSet(Object toElement);返回此set的子集合,由小于toElement的元素组成

SortedSet tailSet(Object fromElement);返回此set的子集合,由大于或者等于fromElement的元素组成

当向TreeSet添加集合时,TreeSet会调用该对象的compareTo(Object obj)方法与集合中的其它元素进行比较,所以这需要集合中的其它元素必须与该元素时同一个对象的实例。所以TreeSet比较两个对象是否是同一个对象的标准是:通过compareTo()方法比较是否返回0,如果返回0,TreeSet会认为这两个对象相同,否则不相同。

如果是程序员自定义的类还需要实现Comparable接口

class R implements Comparable
{
    int count;
    public R(int count)
    {
    this.count=count;
    }
    public String toString()
    {
    return "R[count:"+count+"]";
   
    }
    public boolean equals(Object obj)
    {
    if(this==obj)
    {
    return true;
   
    }
    if(obj!=null&&obj.getClass()==R.class)
    {
     R r=(R)obj;
     if(r.count==this.count)
     {
     return true;
     
     }
   
    }
    return false;
    }
      public int compareTo(Object obj)
      {
     R r=(R)obj;
     return count>r.count?1:
        count<r.count?-1:0;
     
      }
}
public class TreeSet
{
     public static void main(String[] args)
     {
    TreeSet ts=new TreeSet();
    ts.add(new R(5));
    ts.add(new R(-3));
    ts.add(new R(9));
    ts.add(new R(-2));
    System.out.println(ts);

         System.out.println(ts.remove(new R(-2))); //删除field被改变的值,删除失败
    System.out.println(ts);
    System.out.println(ts.remove(new R(5)));  //删除field没被改变的值,删除成功
    System.out.println(ts);
     
     
     }
}

class R是一个可变类,因此可以改变R对象的count实例变量的值,一旦改变了TreeSet集合里可变元素的field,当试图删除该对象时,TreeSet也会删除失败(甚至集合中原有的,field没被修改但与修改后元素相等的元素也无法删除)

<三>EnumSet类

EnumSet类是一个专门为枚举类设计的集合类

import java.util.EnumSet;


enum Season
{
  SPRING,SUMMER,FALL,WINTER
}
public class EnumSetTest
{
  public static void main(String[] args)
  {
  EnumSet es1=EnumSet.allOf(Season.class);
  System.out.println(es1);
  EnumSet es2=EnumSet.noneOf(Season.class);
  System.out.println(es2);
  es2.add(Season.WINTER);
  es2.add(Season.SPRING);
  System.out.println(es2);
  EnumSet es3=EnumSet.of(Season.SUMMER,Season.WINTER);
  System.out.print(es3);
  EnumSet es4=EnumSet.range(Season.SUMMER,Season.WINTER);
  System.out.println(es4);
  EnumSet es5=EnumSet.complementOf(es4);
  System.out.println(es5);
 
  }




}

各Set类的性能分析

HashSet类的性能比TreeSet类的性能好,特别体现在添加,查询元素等操作。对于普通的插入,删除操作,linkedHashSet比HashSet要略慢一点,这是由维护链表所带来的额外开销造成的,不过,因为有了链表,遍历LinkedHashSet会更快。如果需要一个排序的Set时,才该使用TreeSet。EnumSet类是性能最好的





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值