分享

java集合类之总结

 jp乞巧楼 2015-07-29

集合类是java开发非常重要的一个工具,也是经常要用到的,下面将主要从不同集合类的性能方面分析下什么时候用什么集合类比较合适。

 

java集合大致可以分为Set、List和Map三大体系,java5之后又增加了Queue体系集合。Set集合是一个无序不重复的集合(有序的意思是根据你向集合中添加的顺序存放元素),List集合刚好相反是一个有序重复的集合,Map则是具有映射关系的集合。几个集合的父类都是Collection类

 

set集合类:
  set集合判断两个对象相同不是使用==运算符,而是根据equals方法(说到equals方法你应该同时想到hashCode方法)下面介绍其四个实现类HashSet、LinkedHashSet、TreeSet、EnumSet;


  HashSet是Set接口的典型实现,是最常用的Set实现类,当向其中存一个元素的时候,HashSet会调用该对象的hashCode()方法得到该对象的hashCode值(伪地址),然后根据hashCode值向相应的内存中存放元素。如果两个元素的equals相等而它们的hashCode值不同,则HashSet会将它们存放在不同的位置。如果它们的hashCode值相同,但是equals返回值不同,HashSet会在这个位置用链式结构保存多个元素(相当于Hash用链表防止冲突),这样会导致性能下降,所以一般在重写equals方法的时候,也应该重写hashCode方法。
 LinkHashSet原理实现和HashSet基本相同,不同的是它除了根据对象的hashCode值决定存放位置,还使用了链表来维护元素的次序,所以是有序存放的。
 TreeSet是SortedSet接口的实现类,它的数据结构采用的是红黑树,所以它可以对元素进行排序,但元素是不重复的。而且提供了comparator方法可以定制排序,当不使用comParator方法时,它是根据元素的compareTo方法来判断元素大小的,所以在使用TreeSet的时候,如果要重写equals方法,应该注意其compareTo方法也要重写;
    例:(用匿名内部类的方法来实现定制排序) 

TreeSet ts = new TreeSet(new Comparator(){
              public int compare(Object o1, Object o2){
                   M m1 = (M)o1;
                   M m2 = (M)o2;
                   return m1.age > m2.age ? -1:m1.age
              }
}


  EnumSet是一个专为枚举类设计的集合类,EnumSet中所有元素都必须是指定枚举类型的枚举类,该枚举类型在创建EnumSet时显式或隐式地指定。EnumSet集合元素是有序的,EnumSet以枚举值在Enum类内的定义顺序来决定集合元素的顺序。
  各实现类的性能分析:
    HashSet是最常用的,但是其具有不重复无序的特点,LinkedHashSet由于采用链式维护,所以其是有序的,但性能降低了;TreeSet由于需要额外的红黑树来维护集合元素的次序,所以其性能不好,但是如果集合元素需要排序可以考虑用TreeSet;EnumSet是Set实现类中性能最好的,但是它只能保存同一个枚举类的枚举值作为集合元素。但是必须注意的是上面所说的几个实现类都是线程不安全的,如果有多个线程同时访问一个Set集合,则必须手动保证Set集合的同步性,通常可以通过Collections工具类的synchronziedSortedSet方法来包装该Set集合。此操最好的创建时进行,以防止对Set集合的意外非同步访问。例如:
    SortedSet s = Collections.synchronizedSortedSet(new TreeSet(..));

 

List集合类:
   List集合代表一个元素有序、可重复的集合,集合中每个元素都有其对应的顺序索引。List集合允许使用重复元素,可以通过索引来访问指定位置的集合元素,List集合默认按元素的添加顺序设置元素的索引。下面介绍一下它的几个实现类ArrayList、Vector、LinkedList;
  ArrayList与Vector作为List类的两个典型实现,基本功能是一样,只不是Vector出现的早点,ArrayList是后来出现在的,所以ArrayList的方法名可以短一些,两者实现的原理都是封装了一个动态的、允许再分配的Object[]数组,另外ArrayList是线程不安全的,Vector是线程安全的,所以通常尽量少用Vector.
  LinkedList也是List的实现类,它是一个基于链表实现的List类,对于迭代访问,插入、删除的速度非常快,但是如果如果根据索引拿取元素,它就不那么快了,这时应该用ArrayList;另外LinkedList还实现了Deque接口,因此它可以被当成双端队列来使用,自然也可以被当成“栈”来使用,因此现在的程序中需要使用“栈”这种数据结构时,推荐使用ArrayDeueue或LinedList,而不是Stack;


Dueue:
  Deueu用于模拟队列这种数据结构,这种重点讲下PriorityQueue(优先队列)它和TreeStack相似,可以自然排序和定制排序,下面是其的一个应用实例:

public class Queue {

 public static void main(String[] args) {
  PriorityQueue priQueue = new PriorityQueue(1,new Comparator() {
   @Override
   public int compare(Name o1,Name o2) {
    return o1.getName().compareTo(o2.getName());
   }
  });
  
  Name name1 = new Name("zhaojiqiao");
  Name name2 = new Name("jiqiao");
  Name name3 = new Name("qiao");
 
  priQueue.add(name1);
  priQueue.add(name2);
  priQueue.add(name3);
  Name name = null;
  Iterator it = priQueue.iterator();
  //集合式遍历
  while(it.hasNext()){
   Name n = (Name) it.next();
   System.out.println(n.getName());
   
  }
  //删除式遍历
  while((name = (Name)priQueue.poll()) != null){
   System.out.println(name.getName());
  }
 
 }
}


   

Map集合类:
  Map是用来保存具有映射关系的数据,是一个无序不可重复的集合,相当于“关联数组”;Set和Map的关系十分密切,java源码就是先实现了HashMap、TreeMap等集合,然后通过包装一个所有的value都为null的Map集合实现了Set集合类(关于这点,我非常不理解,完全可以用一些Hash,红黑树之类的数据结构来自己实现,而且还不用多包装一个value值,这样的话set的效率应该会好一点,而且可以包装了set之后用来实现Map中的Key啊。。。),所以呢在说Map的时候key值几乎和我们说的set一模一样,所以相似的我就不多提了,下面介绍下Hashtable、HashMap、LinkedHashMap、TreeMap、WeakHashMap、IdentityHashMap、EnumMap这几个实现类;
  Hashtable与HashMap,光看名字就知道Hashtable是一个很古老的实现类,因为他的名字都没有符合驼峰命名规范,而HashMap就是它的替代类,跟ArraySet和Vector一个,HashMap是线程不安全的而Hashtable是线程安全的,但不建议用Hashtable,如果需要同步可以用Collection工具类来进行包装。它们另个一个区别是HashMap里面的key和value值都可以为null,而Hashtable不可以。
  LinkedHashMap和LinkedHashSet一样,是用了一个双链表来维护key-value对我次序,所以它可以实现有序插入,但是性能必然降低了。
  TreeMap实现了SortedMap接口,当然功能也和TreeSet相似,可以自然排序也可以定制排序(排序的对象是Key值)
  IdentityHashMap是HashMap一样,区别是它在判断元素是否相等时用的是==而不是equals方法。
  EnumMap和EnumSet一样,所有的key都必须是单个枚举类的枚举值,创建EnumMap时必须显式或隐式指定它对应的枚举类。
操作集合的工具类Collections(注意不是Collection,不要搞混了)

  java提供了一个操作Set、List、Map等集合的工具类:Collections,该工具类里提供了大量方法对集合进行排序、查询、修改等操作,还提供了将集合对象设置为不可变、对集合对象实现同步控制等方法。前面有篇文章详细的介绍了Collections的用法。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多