Java Collection FramWork

来源:互联网 发布:中世纪黑暗故事 知乎 编辑:程序博客网 时间:2024/04/30 00:59

jdk 的集合框架的主体结构:

接口简述实现操作特性成员要求Set成员不能重复HashSet外部无序地遍历成员。成员可为任意Object子类的对象,但如果覆盖了equals方法,同时注意修改hashCode方法。TreeSet外部有序地遍历成员;附加实现了 SortedSet, 支持子集等要求顺序的操作成员要求实现caparable接口,或者使用  Comparator构造TreeSet。成员一般为同一类型。LinkedHashSet外部按成员的插入顺序遍历成员成员与HashSet成员类似List提供基于索引的对成员的随机访问ArrayList提供快速的基于索引的成员访问,对尾部成员的增加和删除支持较好成员可为任意Object子类的对象LinkedList对列表中任何位置的成员的增加和删除支持较好,但对基于索引的成员访问支持性能较差成员可为任意Object子类的对象Map保存键值对成员,基于键找值操作,compareTo或compare方法对键排序HashMap能满足用户对Map的通用需求键成员可为任意Object子类的对象,但如果覆盖了equals方法,同时注意修改hashCode方法。TreeMap支持对键有序地遍历,使用时建议先用 HashMap增加和删除成员,最后从HashMap生成TreeMap;附加实现了SortedMap接口,支持子Map等要求顺序的操作键成员要求实现caparable接口,或者使用Comparator构造TreeMap。键成员一般为同一类型。LinkedHashMap保留键的插入顺序,用equals 方法检查键和值的相等性成员可为任意Object子类的对象,但如果覆盖了equals方法,同时注意修改hashCode方法。IdentityHashMap使用== 来检查键和值的相等性。成员使用的是严格相等WeakHashMap其行为依赖于垃圾回收线程,没有绝对理由则少用 
Java Collections Framework成员主要包括两种类型,即:Collection和Map类型。 在Java中提供了Collection和Map接口。其中List和Set继承了Collection接口;同时用Vector、ArrayList、 LinkedList三个类实现List接口,HashSet、TreeSet实现Set接口。直接有HashTable、HashMap、 TreeMap实现Map接口。Collection----一组独立的元素,通常这些元素都服从某种规则。List必须保持元素特定的顺序,而Set不能有重复元素。 Map----一组成对的“键值对”对象,即其元素是成对的对象,最典型的应用就是数据字典,并且还有其它广泛的应用。另外,Map可以返回其所有键组成的Set和其所有值组成的Collection,或其键值对组成的Set,并且还可以像数组一样扩展多维 Map,只要让Map中键值对的每个“值”是一个Map即可 Set(interface): 存入Set的每个元素必须是唯一的,因为Set不保存重复元素。加入Set的Object必须定义equals()方法以确保对象的唯一性。Set与 Collection有完全一样的接口。Set接口不保证维护元素的次序。
 

首先还要说一下迭代器:迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。迭代器通常被称为“轻量级”对象,因为创建它的代价小。

(1) 使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。 
(2) 使用next()获得序列中的下一个元素。 
(3) 使用hasNext()检查序列中是否还有元素。 
(4) 使用remove()将迭代器新返回的元素删除。 
Iterator是Java迭代器最简单的实现,为List设计的ListIterator具有更多的功能,它可以从两个方向遍历List,也可以从 List中插入和删除元素。
 


壹--Vector
Vector基于Array的List,性能也就不可能超越 Array,并且Vector是“sychronized”的,这个也是Vector和ArrayList的唯一的区别。Vector 类可以实现可增长的对象数组。与数组一样,它包含可以使用整数索引进行访问的组件。但是,Vector 的大小可以根据需要增大或缩小,以适应创建 Vector 后进行添加或移除项的操作
用法如下:

package  com.zzn.test;
import  java.util.Vector;
public   class  Iterator {
    @SuppressWarnings(
" unchecked " )
    
public   static   void  main(String[] args) {
        
// Vector的创建
          
// 使用Vector的构造方法进行创建
          Vector v  =   new  Vector( 4 );
          
// 向Vector中添加元素
          
// 使用add方法直接添加元素
          v.add( " Test0 " );
          v.add(
" Test1 " );
          v.add(
" Test2 " );
          v.add(
" Test3 " );
          v.add(
" Test4 " );
          
// 从Vector中删除元素
          v.remove( " Test0 " );  // 删除指定内容的元素
          v.remove( 0 );        // 按照索引号删除元素
          
// 获得Vector中已有元素的个数
           int  size  =  v.size();
          System.out.println(
" size: "   +  size);
        
// 遍历Vector中的元素
           for ( int  i  =   0 ;i  <  v.size();i ++ ){
           System.out.println(v.get(i));
          }
    }
}


贰--ArrayList

ArrayList同Vector一样是一个基于Array的,但是不同的是ArrayList不是同步的。所以在性能上要比Vector优越一些,但是当运行到多线程环境中时,可需要自己在管理线程的同步问题。从其命名中可以看出它是一种类似数组的形式进行存储,因此它的随机访问速度极快,动态的增加和减少元素。

package  com.zzn.test;

import  java.util.ArrayList;
import  java.util.List;
import  java.util.Iterator;
/**
 * 迭代ArrayList()的4种方法;
 
*/
public   class  ArrayListTest {
    @SuppressWarnings(
" unchecked " )
    
public   static   void  main(String[] args) {
            List
< String >  list  =   new  ArrayList < String > ();
            list.add(
" aaa " );
            list.add(
" bbb " );
            list.add(
" ccc " );
            
// 方法1
            Iterator it1  =  list.iterator();
            
while (it1.hasNext()){
                System.out.println(it1.next());
            }
            
// 方法2(与方法一大同小异)
             for (Iterator it2  =  list.iterator();it2.hasNext();){
                 System.out.println(it2.next());
            }
            
// 方法3
             for (String tmp:list){
                System.out.println(tmp);
            }
            
// 方法4
             for ( int  i  =   0 ;i  <  list.size(); i  ++ ){
                System.out.println(list.get(i));
            }
    }
}

叁--LinkedList:
LinkedList不同于前面两种List,它不是基于Array的,所以不受Array性能的限制。它每一个节点(Node)都包含两方面的内容:1.节点本身的数据(data);2.下一个节点的信息(nextNode)。所以
当对LinkedList做添加,删除动作的时候就不用像基于Array的List一样,必须进行大量的数据移动。只要更改nextNode的相关信息就可以实现了所以它适合于进行频繁进行插入和删除操作。它具有方法addFirst()、addLast()、getFirst()、 getLast()、removeFirst()、removeLast(),这些方法(没有在任何接口或基类中定义过)使得LinkedList可以当作堆栈、队列和双向队列使用 这就是
LinkedList的优势。Iterator只能对容器进行向前遍历,而 ListIterator则继承了Iterator的思想,并提供了对List进行双向遍历的方法。

 

 package  com.zzn.test;
 
 import  java.util.Iterator;
 import  java.util.LinkedList;
  /** */ /**
  * 迭代ArrayList()的4种方法;
   */
  public   class  LinkedListTest   {
     @SuppressWarnings( " unchecked " )
       public   static   void  main(String[] args)   {
         LinkedList linkedList  =   new  LinkedList();
             linkedList.add( " B " );
             linkedList.add( " C " );
             linkedList.add( " D " );
             linkedList.add( " E " );
             linkedList.add( " F " );
             linkedList.addLast( " Z " );
             linkedList.addFirst( " A " );
             linkedList.add( 1 ,  " A2 " );
             System.out.println( " Original contents of ll:  "   +  linkedList);
 
             linkedList.remove( " F " );
             linkedList.remove( 2 );
             System.out.println( " Contents of ll after deletion:  "   +  linkedList);
 
             linkedList.removeFirst();
             linkedList.removeLast();
             System.out.println( " ll after deleting first and last:  "   +  linkedList);
 
             String val  =  (String)linkedList.get( 2 ); // 第几个位置
             linkedList.set( 2 , val  +   " —Changed " );
             System.out.println( " ll after change:  "   +  linkedList);
            
             Iterator iterator  =   linkedList.iterator();
               while (iterator.hasNext())  {
                 System.out.println(iterator.next());
             }
          }
 }


肆--HashTable
Hashtable继承Map接口,实现一个key-value映射的哈希表。任何非空(non-null)的对象都可作为key或者value。添加数据使用put(key, value),取出数据使用get(key),这两个基本操作的时间开销为常数。

 package  com.zzn.test;
 
 import  java.util.Hashtable;
 
  public   class  HastTableTest   {
       public   static   void  main(String[] args)   {
         Hashtable < String, Integer >  numbers  =   new  Hashtable < String, Integer > ();
        numbers.put( " one " ,  1 );
        numbers.put( " two " ,  2 );
        numbers.put( " three " ,  3 );
       
        Integer n  =  numbers.get( " two " );
            if  (n  !=   null )   {
              System.out.println( " two =  "   +  n);
          }
        }
 }

伍--HashMap
HashMap把各个Object映射起来,实现了“键--值”对应的快速存取。注意,次实现是不同步的。

package  com.zzn.test;

import  java.util.Collection;
import  java.util.HashMap;
import  java.util.Iterator;
import  java.util.Map;

public   class  HashMapTest {
    @SuppressWarnings(
" unchecked " )
    
public   static   void  main(String[] args) {
         HashMap
< String , String >  myMap  =   new  HashMap < String , String > ();
          
          myMap.put(
" hello " " 你好 " );
          myMap.put(
" bye " " 再见 " );
          myMap.put(
" thanks " " 谢谢 " );
          myMap.put(
" ok " " 好的 " );
          
          System.out.println(
" --------------------遍历key和 value---------------------- " );
          
for  (Iterator iter  =  myMap.entrySet().iterator();iter.hasNext();){ 
               Map.Entry element 
=  (Map.Entry)iter.next(); 
               Object strKey 
=  element.getKey();
               Object strObj 
=  element.getValue();
               System.out.println(
" myMap.get(/ "" +strKey+ " / " )= " + strObj);
          }
          
          System.out.println();
          System.out.println(
" --------------------遍历整个 HashMap---------------------- " );
          Collection objs 
=  myMap.entrySet();
          
for  (Iterator iterator = objs.iterator(); iterator.hasNext();){
               Object obj 
=  iterator.next();
               System.out.println(obj);
          }
          
          System.out.println();
          System.out.println(
" --------------------遍历HashMap的 key---------------------- " );
          Collection keys 
=  myMap.keySet();
          
for  (Iterator iterator = keys.iterator(); iterator.hasNext();){
           Object key 
=  iterator.next();
           System.out.println(key);
          }
          
          System.out.println();
          System.out.println(
" --------------------遍历HashMap的 value---------------------- " );
          Collection values 
=  myMap.values();
          
for  (Iterator iterator = values.iterator(); iterator.hasNext();){
           Object value 
=  iterator.next();
           System.out.println(value);
          }
    }

}


陆--TreeMap

package  com.zzn.test;

import  java.util.Iterator;
import  java.util.Map;
import  java.util.TreeMap;

public   class  TreeMapTest {

    
public   static   void  main(String[] args) {
        TreeMap tm 
=   new  TreeMap();  
        
for  ( int  i  =   0 ; i  <   10 ; i ++ ) {  
            String a 
=   " key "   +  i;  
            String b 
=   " value "   +  i;  
            tm.put(a, b);  
        }  
        
//  第一种方法  
        
//  使用entrySet()方法生成一个由Map.entry对象组成的Set,  
        
//  而Map.entry对象包括了每个元素的"键"和"值".这样就可以用 iterator了  
           Iterator it  =  tm.entrySet().iterator();  
           
while  (it.hasNext()) {  
        
//  entry的输出结果如key0=value0等  
           Map.Entry entry  = (Map.Entry) it.next();  
           Object key 
=  entry.getKey();  
           Object value
= entry.getValue();  
           System.out.println(entry);  
           System.out.println(key);  
           System.out.println(value);  
          }  
  
        
// 第二种方法  
        
// 这是用TreeMap的keySet()方法,生成的对象是由key对象组成的 Set  
        
// 再利用TreeMap的get(key)方法,得到对应的value值  
           Iterator ite  =  tm.keySet().iterator();  
           
while  (ite.hasNext()) {  
           
// it.next()得到的是key,tm.get(key)得到obj  
           System.out.println(tm.get(ite.next()));  
        }  
    }
}

柒--LindedHashMap
LinkedHashMap扩展HashMap,以插入顺序将关键字/值对添加进链接哈希映像中。象LinkedHashSet一样,LinkedHashMap内部也采用双重链接式列表

 

package  com.zzn.test;
import
 java.util.Collection;
import
 java.util.Iterator;
import
 java.util.LinkedHashMap;
public   class
 LinkedHashMapTest {
@SuppressWarnings(
" unchecked "
)
public   static   void
 main(String[] args) {
    LinkedHashMap lHashMap 
=   new
 LinkedHashMap();
        lHashMap.put(
" One " new  Integer( 1
));
        lHashMap.put(
" Two " new  Integer( 2
));
        lHashMap.put(
" three " new  Integer( 3
));
        lHashMap.put(
" four " new  Integer( 4
));
        
        
        System.out.println(
" ~~~~~~方法一:迭代LinkedHashMap类型的 lHashMap;~~~~~~ "
);
        
for (Iterator it =
lHashMap.values().iterator();it.hasNext();){
             System.out.println(it.next());
        }
        System.out.println(
" ~~~~~~方法二:迭代LinkedHashMap类型的 lHashMap;~~~~~~ "
);
        Collection c 
=
 lHashMap.values();
        Iterator iter 
=
 c.iterator();
        
while
 (iter.hasNext()){
          System.out.println(iter.next());
        }
        
        System.out.println(
" ~~~~~~Get Set view of Keys from Java LinkedHashMap;~~~~~~ "
);
        Iterator itr 
=
 lHashMap.keySet().iterator();
        
while
 (itr.hasNext()){
          System.out.println(itr.next());
        }
        
// key - 要测试其是否在此映射中存在的键 

         boolean  blnExistKey  =  lHashMap.containsKey( " Two " );
        System.out.println(blnExistKey);
        
// value - 要测试其是否在此映射中存在的值 

         boolean  blnExistValue  =  lHashMap.containsValue( " 1 " );
        System.out.println(blnExistValue);
        
        
        System.out.println(
" ~~~~~~从LinkedHashMap中移除key为 “Two”的值;~~~~~~ "
);
        Object obj 
=  lHashMap.remove( " Two " ); // 从LinkedHashMap中移除key为“Two”的值;

        System.out.println(obj +   "  Removed from LinkedHashMap " );   // 输出移除的值;
    }
}

捌--HashSet
此类实现 Set 接口,它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。此类为基本操作提供了稳定性能,这些基本操作包括 addremovecontainssize;次实现是不同步的;为快速查找而设计的Set。存入HashSet的对象必须定义hashCode();

package  com.zzn.test;
import  java.util.HashSet;
import  java.util.Iterator;
public   class  HashSetTest {
    @SuppressWarnings(
" unchecked " )
    
public   static   void  main(String[] args)
    {
      HashSet hashSet
= new  HashSet();
      String a
= new  String( " A " );
      String b
= new  String( " B " );
      String c
= new  String( " B " );
      String d
= " D " ;
      hashSet.add(a);
      hashSet.add(b);
      hashSet.add(d);
      System.out.println(
" ~~~~~~~~~~~b和c得值相同;所以size()是3~~~~~~~~~~~ " );
      System.out.println(hashSet.size());
      String cz
= hashSet.add(c) ? " 此对象不存在 " : " 已经存在 " ;
      System.out.println(
" 测试是否可以添加对象     " + cz);
      System.out.println(
" ~~~~~~~~~~~测试是否为空;~~~~~~~~~~~ " );
      System.out.println(hashSet.isEmpty());
      System.out.println(
" ~~~~~~~~~~~测试其中是否已经包含某个对象;~~~~~~~~~~~ " );
      System.out.println(hashSet.contains(
" A " ));
      System.out.println(
" ~~~~~~~~~~~迭代;~~~~~~~~~~~ " );
      Iterator ir
= hashSet.iterator();
      
while (ir.hasNext())
      {
       System.out.println(ir.next());
      }
      System.out.println(
" ~~~~~~~~~~~测试某个对象是否可以删除;~~~~~~~~~~~ " );
      System.out.println(hashSet.remove(
" a " ));
      System.out.println(hashSet.remove(
" A " ));
      System.out.println(
" ~~~~~~~~~~~经过测试,如果你想再次使用ir变量,必须重新更新以下;~~~~~~~~~~~ " );
      ir
= hashSet.iterator();
      
while (ir.hasNext())
      {
       System.out.println(ir.next());
      }
    }
}

玖--LindedHashSet
具有HashSet的查询速度,且内部使用链表维护元素的顺序(插入的次序)。于是在使用迭代器遍历 Set时,结果会按元素插入的次序显示。
package  com.zzn.test;
import  java.util.Iterator;
import  java.util.LinkedHashSet;
public   class  LinkedHashSetTest {
    
public   static   void  main(String[] args) {
        LinkedHashSet
< Integer >  lhashSet  =   new  LinkedHashSet < Integer > ();
        lhashSet.add(
new  Integer( " 1 " ));
        lhashSet.add(
new  Integer( " 2 " ));
        lhashSet.add(
new  Integer( " 3 " ));
        System.out.println(
" ~~~~~~~~~~~~~~~把LinkedHashSet的所有元素复制到 Object Array中~~~~~~~~~~~~~~~ " );
        Object[] objArray 
=  lhashSet.toArray();
        
for  (Object inte: objArray){
          System.out.println(inte);
        }
        System.out.println(
" ~~~~~~~~~~~~~~~检查lhashSet中是否存在值为3的元素~~~~~~~~~~~~~~~ " );
        
boolean  bool  =  lhashSet.contains( new  Integer( " 3 " ));
        System.out.println(bool);
        
        System.out.println(
" ~~~~~~~~~~~~~~~迭代lhashSet~~~~~~~~~~~~~~~ " );
        
for (Iterator it  = lhashSet.iterator();it.hasNext();){
            System.out.println(it.next());
        }
      }
}
拾--TreeSet
TreeSet: 保持次序的Set,底层为树结构。使用它可以从Set中提取有序的序列,TreeSet 为使用树来进行存储的Set接口提供了一个工具,对象按升序存储.访问和检索是很快的。在存储了大量的需要进行快速检索的排序信息的情况下,TreeSet 是一个很好的选择。
package  com.zzn.test;

import  java.util.Iterator;
import  java.util.TreeSet;
public   class  TreeSetTest {
    @SuppressWarnings(
" unchecked " )
    
public   static   void  main(String[] args) 
     {
      System.out.println(
" ~~~~~~~~~~~~~~TreeSet的排序功能~~~~~~~~~~~~~~~ " );
      TreeSet ts 
=   new  TreeSet();
      ts.add(
" B " );
      ts.add(
" C " );
      ts.add(
" A " );
      ts.add(
" E " );
      ts.add(
" F " );
      ts.add(
" D " );
      
// 注意如果TreeSet中有重复(一样的)值,TreeSet会把其他相同的排除掉;
      ts.add( " A " );
      System.out.println(ts);
      System.out.println(
" ~~~~~~~~~~~~~~TreeSet的迭代~~~~~~~~~~~~~~~ " );
      
for (Iterator it  = ts.iterator();it.hasNext();){
          System.out.println(it.next());
      }
  }
}


下面说一下他们之间的区别
一、Hashtable和HashMap的区别:
        ①都属于 Map 接口的类,实现了将惟一键映射到特定的值上。 Hashtable 是Dictionary的子类,HashMap是Map接口的一个实现类;
        ②Hashtable中的方法是同步的,而HashMap中的方法在缺省情况下是非同步的。即是说,在多线程应用程序中,不用专门的操作就安全地可以使用Hashtable了;而对于HashMap,则需要额外的同步机
            制。但HashMap的同步问题可通过Collections的一个静态方法得到解决:Map Collections.synchronizedMap(Map m)这个方法返回一个同步的Map,这个Map封装了底层的 HashMap的所有方法,使得底层
            的HashMap即使是在多线程的环境中也是安全的。
        ③HashMap 类没有分类或者排序。它允许一个 null 键和多个 null 值。 Hashtable 类似于 HashMap ,但是不允许 null 键和 null 值。它也比 HashMap 慢,因为它是同步的。
        ④HashMap被优先选择。
二、ArrayList和LinkedList
       ① ArrayList 其实是包装了一个数组 Object[] ,当实例化一个 ArrayList 时,一个数组也被实例化,当向 ArrayList 中添加对象是,数组的大小也相应的改变。这样就带来以下有缺点:
           快速随即访问
你可以随即访问每个元素而不用考虑性能问题,通过调用 get(i) 方法来访问下标为 i 的数组元素。
           向其中添加对象速度慢
当你创建数组是并不能确定其容量,所以当改变这个数组时就必须在内存中做很多事情。
           操作其中对象的速度慢
当你要想数组中任意两个元素中间添加对象时,数组需要移动所有后面的对象。
        
LinkedList 是通过节点直接彼此连接 来实现的。每一个节点都包含前一个节点的引用,后一个节点的引用和节点存储的值。当一个新节点插入时,只需要修改其中保持先后关系的节点的引用即可,
           当删除记录时也一样。这样就带来以下有缺点:
 
           操作其中对象的速度快 只需要改变连接,新的节点可以在内存中的任何地方
           
不能随即访问 虽然存在 get() 方法,但是这个方法是通过遍历接点来定位的所以速度慢。
        ③当一些被定义好的数据需要放到与数组对应的 List 中, ArrayList 是很好的选择,因为它可以动态变化,但是不要在整个应用程序用频繁的使用。当你要很方便的操作其中的数据而不用随即访问时
            LinkList
是很好的选择。如果你要频繁随即访问建议使用数组。

原创粉丝点击