Java集合总结

本文详细介绍了Java集合框架,包括Collection、List、Set、Queue和Map接口及其特点。讨论了ListIterator的优势,如双向遍历和元素操作。还讲解了集合与数组之间的转换,线程安全的集合类如Vector和HashTable,以及HashMap在多线程下的问题。最后提到了Collections工具类和遗留集合的重要性。
摘要由CSDN通过智能技术生成

PS:

       

List集合的特有迭代器是什么---特有的迭代器是listIterator

              List和Set都有iterator()来取得其迭代器。对List来说,你还可以通过listIterator()取得其迭代器,两种迭代器在有些时候是不能通用的,Iterator和ListIterator主要区别在以下方面:

1. ListIterator有add()方法,可以向List中添加对象,而Iterator不能。Iterator是ListIterator的父接口。

2. ListIterator和Iterator都有hasNext()和next()方法,可以实现顺序向后遍历,但是ListIterator有hasPrevious()和previous()方法,可以实现逆向(顺序向前)遍历。Iterator就不可以。

3. ListIterator可以定位当前的索引位置,nextIndex()和previousIndex()可以实现。Iterator没有此功能。

4. 都可实现删除对象,但是ListIterator可以实现对象的修改,set()方法可以实现。Iierator仅能遍历,不能修改。

因为ListIterator的这些功能,可以实现对LinkedList等List数据结构的操作。其实,数组对象也可以用迭代器来实现。

org.apache.commons.collections.iterators.ArrayIterator就可以实现此功能。一般情况下,我们使用Iterator就可以了,如果你需要进行记录的前后反复检索的话,你就可以使用ListIterator来扩展你的功能,(有点象JDBC中的滚动结果集)

5  ListIterator中具备着对被遍历的元素进行增删改查的方法,可以对元素进行逆向遍历


一 前言:讲集合collection之前,我们先分清三个概念:

    colection 集合,用来表示一种数据结构(集合--逻辑结构的一种)
      

       Collection 集合接口,指的是 java.util.Collection接口,是 Set、List 和 Queue 接口的超类接口    
     

       Collections 集合工具类,指的是 java.util.Collections 类。



  Collection完整图---VS---重点学习图


  

 重点学习图:(如下)


二   分别介绍

   
  这里说的集合指的是小写的collection(集合数据结构),集合有4种基本形式,其中前三种的父接口是Collection(集合接口)

  1. List 关注事物的索引列表
  2. Set 关注事物的唯一性
  3. Queue 关注事物被处理时的顺序
  4. Map 关注事物的映射和键值的唯一性

(一) List

                   List接口:有序的列表,允许重复元素,它的有序是指假如元素时的顺序。
                  
                    1) ArrayList:  数组列表。内部采用数组结构来存储元素, 根据索引来存取元素的效率很高 
                                                           适合于:要遍历显示所有元素的情况。不适合需要频繁增删元素的情况。
                    2) LinkedList:链式列表。内部采用双向链表结构来存储元素.适合于:需要频繁增删元素的情况下。但不要使用根据索引来获取元素。
                     
                     双向链表结构不仅可以后向迭代,还可以前向迭代,并且支持元素的修改。
               



  ArrayList 可以将它理解成一个可增长的数组,它提供快速迭代和快速随机访问的能力。

    LinkedList 中的元素之间是双链接的,当需要快速插入和删除时LinkedList成为List中的不二选择。

  Vector 是ArrayList的线程安全版本,性能比ArrayList要低,现在已经很少使用.

              Stack继承自Vector,实现一个后进先出的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。基本的push和pop方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈。
    

(二)Set 

            允许重复元素(equals相等)的集合接口。
         
            1) 要存放到Set接口中的对象,它对应的类应该重写equals方法和hashCode方法,
                 以实现业务意义上的相等规则。 
            2) 常用的数据类型:8种基本数据类型包装类、String类、Date类、Calendar类它们
                都重写了equals和hashCode方法。

          HashSet: 内部采用散列表来存储元素。

           a) 散列表的存储原理:
                 首先获取对象的哈希码值,根据这个值用固定算法计算出它在散列表中的存储位置;把对象存储 到散列表 的指定位置。存储到指定位置时,先看指定位置原来是否已经存在对象,如果存在,还需要进行equals比较(如果equals相等,说明存在重复元素,不存放,否则存放)。
          
           b) 散列表存取对象的效率最高。
            
           c) 适合情况:不允许重复元素,又不在乎存取顺序。
 
            LinkedHashSet: 内部采用散列表和双向链表结构来存储元素。 
                                
                                         适合情况:不允许重复元素,但又需要保存元素的顺序。 

          TreeSet:树集。内部使用红黑树来存储排序的元素。
             
             a) 一种方式,存入的对象对应的类实现了Comparable接口。
        
             b) 另一种方式,把一个比较器(实现Comparator接口的类)的对象传入该类的构造器来创建指定比较器的树
                                       集对象。
                                     
      注:  Comparable接口和Comparator接口
    
      a) 可排序的类必须实现java.lang.Comparable接口,在compareTo方法中定义比较规则。
         int compareTo(T t);如果当前对象小于指定对象,返回负整数;大于,返回正整数。等于,返回0。

      b) 为了便于使用各种排序规则的要求,可以通过实现Comparator<T>接口来定义比较器类。
         int compare(T t1, T t2);如果t1对象小于t2对象,返回负整数;大于,返回正整数。等于,返回0。


                
         HashSet 当不希望集合中有重复值,并且不关心元素之间的顺序时可以使用此类。哈希表是通过使用称为散列法的机制来存储信息的,是专门为快速查询而设计的。存入 HashSet的对象必须定义hashCode方法。元素并没有以某种特定顺序来存放

         LinkedHashset 当不希望集合中有重复值,并且希望按照元素的插入顺序进行迭代遍历时可采用此类。内部使用散列以加快查询速度,同时使用链表维护元素插入的次序,在使用迭代器遍历Set时,结果会按元素插入的次序显示。

         TreeSet 当不希望集合中有重复值,并且希望按照元素的自然顺序进行排序时可以采用此类。TreeSet采用红黑树的数据结构进行排序元素,使用它可以从 Set中提取有序(升序或者降序)的序列。需要注意的是,存入自定义类时,TreeSet需要维护元素的存储顺序,因此自定义类要实现Comparable接口并定义compareTo方法。若不实现Comparable接口/Comparator接口,则按自然顺序意思是某种和插入顺序无关,而是和元素本身的内容和特质有关的排序 方式,譬如“abc”排在“abd”前面

      
          
        Set 之  PS:

                1   Set不允许包含相同的元素,如果试图把两个相同元素加入同一个集合中,add方法返回false。 
                     
Set判断两个对象相同不是使用==运算符,而是根据equals方法。也就是说,只要两个对象用equals方法比较返回true,Set就不 会接受这两个对象。 
                
               2   HashSet 不能保证元素的排列顺序,顺序有可能发生变化 ,不是同步的 ,集合元素可以是null,但只能放入一个null 。
                    当向HashSet结合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据 hashCode值来决定该对象在                           HashSet中存储位置。 简单的说,HashSet集合判断两个元素相等的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode()方法返回值相                       等 。注意,如果要把一个对象放入HashSet中,重写该对象对应类的equals方法,也应该重写其hashCode()方法。其规则是如果两个对 象通过equals方法                     比较返回true时,其hashCode也应该相同。另外,对象中用作equals比较标准的属性,都应该用来计算 hashCode的值。
              
              3    TreeSet是SortedSet接口的唯一实现类,TreeSet可以确保集合元素处于排序状态。TreeSet支持两种排序方式,自然排序 和定制排序,其中自然排序为默                    认的排序方式。向TreeSet中加入的应该是同一个类的对象。 TreeSet判断两个对象不相等的方式是两个对象通过equals方法返回false,或者通过                                    CompareTo方法比较没有返回0 自然排序是根据集合元素的大小,以升序排列,如果要定制排序,应该使用Comparator接口,实现
                   int compare(T o1,T o2)方法自然排序是根据集合元素的大小,以升序排列,如果要定制排序,应该使用Comparator接口,实现 int compare(T o1,T o2)方法

(三)Queue(用于保存将要执行的任务列表。

       
       LinkedList 同样实现了Queue接口,可以实现先进先出的队列。
      
       PriorityQueue 用来创建自然排序的优先级队列。番外篇中有个例子http://android.yaohuiji.com/archives/3454你可以看一下
    
       PriorityQueue优先级队列相关知识之  PS:
         
                   1.一个基于优先级堆的无界优先级队列。优先级队列的元素按照其自然顺序进行排序,或者根据构造队列时提供的 Comparator 进行排序,具体取决于所使用 的构造方法。优先级队列不允许使用 null 元素。依靠自然顺序的优先级 队列还不允许插入不可比较的对象(这样做可能导致 ClassCastException);
      
                   2.此队列的头 是按指定排序方式确定的最小 元素。如果多个元素都是最小值,则头是其中一个元素——选择方法是任意的。队列获取操作 poll、remove、peek 和 element 访问处于队列头的元素;
     
                   3.poll()方法:获取并移除此队列的头,如果此队列为空,则返回 null;
     
                   4.peek()方法:获取但不移除此队列的头;如果此队列为空,则返回 null。
       

(四) Map (  Map关心的是唯一的标识符。他将唯一的键映射到某个元素。当然键和值都是对象。

             1) HashMap:哈希映射(散列映射)。内部采用散列表来存储键/值对的键。

                    a) 作为映射对的键对应的类要重写equals和hashCode方法,以实现键相等规则。
                    b) 因为键是用散列表存放的,所以键/值对在Map中的存放是无序的。
                    c) 适合于:需要以键/值对形式存放元素时。它的存取效率很高。它是使用频率最高的一个集合类。

            2)LinkedHashMap:内部采用哈希表和双向链表来存储,键/值对的存放有序。
     
           3)TreeMap:树结构映射。内部使用红黑树来存储排序的键

               a) 一种方式,存入的键对应的类实现了Comparable接口。
               b) 另一种方式,把一个针对键的比较器(实现Comparator接口的类)对象传入该类的构造器来创建。

   

          HashMap 当需要键值对表示,又不关心顺序时可采用HashMap。HashMap的key为唯一,value可重复。key与value允许为null值,但key仅能有一个null值。 HashMap非线程安全  。如果需要同步,可以用 Collections的synchronizedMap方法使HashMap具有同步的能力,或者使用ConcurrentHashMap。
                  
          Hashtable 注意Hashtable中的t是小写的,它是HashMap的线程安全版本,现在已经很少使用。而其子类Properties经常会使用 它不允许记录的键或者值为空;它支持线程的同步,是线程安全的。

          LinkedHashMap 当需要键值对,并且关心插入顺序时可采用它。LinkedHashMap保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的.也可以在构造时用带参数,按照应用次数排序。在遍历的时候会比HashMap慢,不过有种情况例外,当HashMap容量很大,实际数据较少时,遍历起来可能会比LinkedHashMap慢,因为LinkedHashMap的遍历速度只和实际数据有关,和容量无关,而HashMap的遍历速度和他的容量有关。LinkedHashMap也是一个HashMap,但是内部维持了一个双向链表,可以保持顺序。(因为是双向链表,其除了能向后遍历,还支持向前遍历,并可在遍历过程中删除元素)

         TreeMap 当需要键值对,并关心元素的自然排序时可采用它。TreeMap实现SortMap接口,能够把它保存的记录根据键排序,默认是按键值的升序排序,也可以指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。不仅可以保持顺序,而且可以用于排序.
  
      Map之   PS: 
                一般情况下,我们用的最多的是HashMap,HashMap里面存入的键值对在取出的时候是随机的,它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度。在Map 中插入、删除和定位元素,HashMap 是最好的选择。
                    TreeMap取出来的是排序后的键值对。但如果您要按自然顺序或自定义顺序遍历键,那么TreeMap会更好。
                    LinkedHashMap 是HashMap的一个子类,如果需要输出的顺序和输入的相同,那么用LinkedHashMap可以实现,它还可以按读取顺序来排列,像连接池中可以应用。

三   列表、集合与数组的互相转换

  1 List、Set转为数组

   List转换成数组可以使用List的toArray方法,返回一个Object数组。
   Set转换成数组可以使用Set的toArray方法,返回一个Object数组。
               如果List或者Set中元素的 类型 都为 A,那么可以使用带参数的toArray方法,将得到类型为A的数组,具体语句是(A[])set.toArray(new A[0]),例: ArrayList<Integer>  lt=new  ArrayList<Integer>();
                                                             int [ ] tmp={ };
                                                             int [ ] target = (int [ ] )lt.toArray(tmp); 

2 数组只能直接转化为List

    

        数组转换成List可以使用Arrays的asList静态方法,得到一个List。

                   例如:  String[] sa ={"one","two","three","four"}; 
                                List list = Arrays.asList(sa);

      数组转换成Set时,需要先将数组转换成List,再将List构造Set。 List  lt=new  HashSet( List) ; 使用Set的构造函数,函数参数为Collection类型。

                   public HashSet(Collection<? extends E> c) {  }

                   public ArrayList(Collection<? extends E> c) { }  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值