java集合

java 集合

    java.util包下有两个所有集合的父接口

    Collection 和 Map
   

Collection extends自 --java.lang.Iterable接口 其下为:
       +List 接口
          -ArrayList 类
          -LinkedList 类
          -Vector 类     此类是实现同步的

       +Queue 接口
          +不常用,在此不表.

       +Set 接口
          +SortedSet 接口
             -TreeSet 类 (红黑树,自平衡2叉查找树)
          -HashSet

Map下则为
      -HashMap 类 (除了不同步和允许使用 null 键/值之外,与 Hashtable 大致相同.)
      -Hashtable 类 此类是实现同步的,不允许使用 null 键值
      +SortedMap 接口
         -TreeMap 类 (实现可明确保证其顺序,HashMap,HashTable等实现迭代器不保证器顺序)

  

此外用来存集合数据的还有一种,就是最基本的引用类型 数组Array(相同类型数据的集合) 

type[] 变量名 = new type[数组中元素的个数];  如: int[] a = new int[10];

   等同的定义方式有如下几种:
   class Db{}
   Db[] c = new Db[10]; 或者  Db c[] = new Db[10];  或者
   Db[] c = { new Db(),new Db() };  或者  Db[] c = new Db[]{ new Db(), new Db() }; 写法可以自由组合,每个数组都有一个属性length

   二维数组即 数组的数组,或者说用数组组成的数组
   type[][] i = new type[2][3]; 或者  type i[][] = new type[2][3];
   参考: http://www.cnblogs.com/mengdd/archive/2013/01/04/2844264.html


   然后说一下数组存取数据的问题
   1.效率高,但容量固定且无法动态改变。
   2.无法直接判断其中实际存有多少元素,length只是告诉我们array的容量.
   3.数据操作提供了java.util.Arrays类,这个类里有一些静态方法
     如:equals():比较两个array是否相等。array拥有相同元素个数,且所有对应元素两两相等。
        fill():将值填入array中。
        sort():用来对array进行排序。
        binarySearch():在排好序的array中寻找元素。
        System.arraycopy():array的复制。

   用集合类的情况其实更多一些,因为很多时候需要处理未知数量的对象,容量不足时可以自动扩展容量

   集合类上分collection和map两大类 固有方法size() 相当于数组的length属性,

   此外也有提供静态的帮助方法的类 Java.util.Collections;collection 内使用位置index下标,每个下标一个元素
   map 内使用 key--value键值对的方式

   collection下细分两类list 和 set , list:以特定次序存储元素  set:不能含有重复的元素

    确切的说:set 不包含满足 e1.equals(e2) 的元素对 e1 和 e2,并且最多包含一个 null 元素


   map下主要使用的是这两类 HashMap 和 HashtTable, 

   HashMap:操作不同步和允许使用 null 键/值   HashTable:此类是实现同步的,不允许使用 null 键值
     Map可以返回其所有键组成的Set和其所有值组成的Collection,或其键值对组成的Set,
     并且还可以像数组一样扩展多维Map,只要让Map中键值对的每个“值”是一个Map即可

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

   1. iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。
   注意:iterator()方法是java.lang.Iterable接口,被Collection继承。

   2. next()获得序列中的下一个元素。

  3. hasNext()检查序列中是否还有元素。

  4. remove()将迭代器新返回的元素删除。
   示例:
   

 1.Iterator it = list.iterator();
    while (it.hasNext()) {
        personnelID= (String) it.next();
    }
    or..
 2.List<String> arraylist = new ArrayList<String>();
    for (String str:arraylist) {
        System.out.println(str);
    }
    or..
 3.for (int i=0; i<list.size(); i++) {
        value = (String)list.get(i);       
    }
    //实际访问一个元素的效率上,3效率最高(耗时最短),2其次,1耗时最长,但就可用性易用性而言,通常优先使用1


    002 list的功能方法
    List(interface): 次序是List最重要的特点;它确保维护元素特定的顺序。
    一个List可以生成ListIterator,使用它可以从两个方向遍历List,也可以从List中间插入和删除元素。

    ArrayList: 由数组实现的List。它允许对元素进行快速随机访问,但是向List中间插入与移除元素的速度很慢。ListIterator只应该用来由后向前遍历ArrayList,而不是用来插入和删除元素,因为这比LinkedList开销要大很多。

    LinkedList: 由列表实现的List。对顺序访问进行了优化,向List中间插入与删除得开销不大,随机访问则相对较慢(可用ArrayList代替)。它具有方法addFirst()、addLast()、getFirst()、getLast()、removeFirst()、removeLast(),这些方法(没有在任何接口或基类中定义过)使得LinkedList可以当作堆栈、队列和双向队列使用

  

//具体使用:
   //在使用List集合时,通常情况下声明为List类型,实例化时根据实际情况的需要,实例化为ArrayList或LinkedList,
    例:List<String> l = new ArrayList<String>();
    它的方法:
    add(int index, Object obj) 向指定索引位置添加对象
    set(int index, Object obj) 修改指定索引位置的对象
    get(int index)             访问指定索引位置的对象
    如:
        String a = "A", b = "B", c = "C", d = "D", e = "E";
        List<String> list = new LinkedList<String>();
        list.add(a);
        list.add(e);
        list.add(d);
        list.set(1, b);// 将索引位置为1的对象e修改为对象b
        list.add(2, c);// 将对象c添加到索引位置为2的位置
        
        Iterator<String> it = list.iterator();
        while (it.hasNext()){
            System.out.println(it.next());  //输出 ABCD
        }
        
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));// 利用get(int index)方法获得指定索引位置的对象
        }   

    indexOf(Object obj)      获得指定对象的最小的索引位置
    lastIndexOf(Object obj)        获得指定对象的最大的索引位置
    这两个方法的前提条件是, 指定的对象在List集合中具有重复的对象,
    如果在List集合中有且仅有一个指定的对象,则通过这两个方法获得的索引位置是相同的

        String a = "A", b = "B", c = "C", d = "D", repeat = "Repeat";
        List<String> list = new ArrayList<String>();
        list.add(a);          // 索引位置为 0
        list.add(repeat);      // 索引位置为 1
        list.add(b);          // 索引位置为 2
        list.add(repeat);      // 索引位置为 3
        list.add(c);          // 索引位置为 4
        list.add(repeat);      // 索引位置为 5
        list.add(d);          // 索引位置为 6

        System.out.println(list.indexOf(repeat));    // 输出 1
        System.out.println(list.lastIndexOf(repeat)); // 输出 5
        System.out.println(list.indexOf(b));          // 输出 2
        System.out.println(list.lastIndexOf(b));      // 输出 2

    subList(int fromIndex, int toIndex)   截取现有List集合中的部分对象生成新的List集合
    注意:新生成的集合中包含起始索引位置代表的对象,但是不包含终止索引位置代表的对象
    
        String a = "A", b = "B", c = "C", d = "D", e = "E";
        List<String> list = new ArrayList<String>();
        list.add(a);          // 索引位置为 0
        list.add(b);          // 索引位置为 1
        list.add(c);          // 索引位置为 2
        list.add(d);          // 索引位置为 3
        list.add(e);          // 索引位置为 4
        
        list = list.subList(1, 3);    // 利用从索引位置 1 到 3 的对象重新生成一个List集合
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));   // 输出 B C
        }


    003 set的功能方法   set同样可以使用iterator,foreach循环 add 等方法参考以上...
    Set(interface): 存入Set的每个元素必须是唯一的,这也是与List不同的,因为Set不保存重复元素。加入Set的Object必须定义equals()方法以确保对象的唯一性。Set与Collection有完全一样的接口。Set接口不保证维护元素的次序

  HashSet: HashSet能快速定位一个元素,存入HashSet的对象必须定义hashCode()

  TreeSet: 保持次序的Set,底层为树结构。使用它可以从Set中提取有序的序列

  LinkedHashSet: 具有HashSet的查询速度,且内部使用链表维护元素的顺序(插入的次序)。
    于是在使用迭代器遍历Set时,结果会按元素插入的次序显示。

    notice:
  HashSet采用散列函数对元素进行排序,这是专门为快速查询而设计的;
    TreeSet采用红黑树的数据结构进行排序元素;
    LinkedHashSet内部使用散列以加快查询速度,同时使用链表维护元素的次序,使得看起来元素是以插入的顺序保存的。
    需要注意的是,生成自己的类时,Set需要维护元素的存储顺序,因此要实现Comparable接口并定义compareTo()方法。
    List,Set,Map将持有对象一律视为Object型别。
    Collection、List、Set、Map都是接口,不能实例化。
    继承自它们的 ArrayList, Vector, HashTable, HashMap是具象class,这些才可被实例化。
    vector容器确切知道它所持有的对象隶属什么型别。vector不进行边界检查。

    Map
    定义:  

   Map map = new HashMap();  //声明

    map.put("sa","dd");  // 放值

    String str = map.get("sa").toString //取值

    // 遍历
    for(Object obj : map.keySet()){
        Object value = map.get(obj );
    }

    Map这个类没有继承Iterable接口所以不能直接通过map.iterator来遍历 list,set就是实现了这个接口,所以可以直接遍历
    于是先转化为set类型,用entrySet()方法,其中set中的每一个元素值就是map中的一个键值对,也就是Map.Entry<K,V>了,然后就可以遍历了
    entrySet()的返回值也是返回一个Set集合,此集合的类型为Map.Entry
    Map.Entry是Map声明的一个内部接口,此接口为泛型,定义为Entry<K,V>。
    它表示Map中的一个实体(一个key-value对)。接口中有getKey(),getValue方法

    Irerator iterator = map.entrySet().iterator();
    while(iterator.hasNext()) {
        Map.Entry entry = iterator.next();
        Object key = entry.getKey();
    }
    or...

    Set  keySet= map.keySet();
    Irerator iterator = keySet.iterator;
    while(iterator.hasNext()) {
        Object key = iterator.next();
        Object value = map.get(key);
    }
    or...

    Collection c = map.values();
    Iterator iterator = c.iterator();
    while(iterator.hasNext()) {
        Object value = iterator.next();
    }

    参考: http://www.cnblogs.com/guanjie20/p/3769688.html


    map常用功能方法:
   

   void clear()      从此映射中移除所有映射关系(可选操作)
  boolean containsKey(Object key)      如果此映射包含指定键的映射关系,则返回 true
  boolean containsValue(Object value) 如果此映射将一个或多个键映射到指定值,则返回 true
  Set<Map.Entry<K,V>> entrySet() 返回此映射中包含的映射关系的 Set 视图
  boolean equals(Object o) 比较指定的对象与此映射是否相等
  V
get(Object key) 返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null
  
int hashCode() 返回此映射的哈希码值。
  boolean isEmpty() 如果此映射未包含键
-值映射关系,则返回 true
  Set<K> keySet() 返回此映射中包含的键的 Set 视图
  V put(K key, V value) 将指定的值与此映射中的指定键关联(可选操作)
  
void putAll(Map<? extends K,? extends V> m) 从指定映射中将所有映射关系复制到此映射中(可选操作)
  V remove(Object key) 如果存在一个键的映射关系,则将其从此映射中移除(可选操作)
  
int size() 返回此映射中的键-值映射关系数
  Collection
<V> values() 返回此映射中包含的值的 Collection 视图

    注意:
     将可变对象用作映射键时必须格外小心。
     当对象是映射中某个键时,如果以影响 equals 比较的方式更改了对象的值,则映射的行为将是不确定的。
     另一件禁止项是:不允许某个映射将自身作为一个键包含。虽然允许某个映射将自身作为值包含,但请格外小心:
     在这样的映射上 equals 和 hashCode 方法的定义将不再是明确的。


    注意:
    容器类仅能持有对象引用(指向对象的指针),而不是将对象信息copy一份至数列某位置。
    一旦将对象置入容器内,便损失了该对象的型别信息。
    在各种Lists中,最好的做法是以ArrayList作为缺省选择。当插入、删除频繁时,使用LinkedList();
    Vector总是比ArrayList慢,所以要尽量避免使用。
    在各种Sets中,HashSet通常优于HashTree(插入、查找)。只有当需要产生一个经过排序的序列,才用TreeSet。
    最常用的是ArrayList,HashSet,HashMap,Array。而且,我们也会发现一个规律,用TreeXXX都是排序的。
   
    其它补充:
    Collection没有get()方法来取得某个元素。只能通过iterator()遍历元素,
    List,可以通过get()方法来一次取出一个元素。使用数字来选择一堆对象中的一个,get(0)...。(add/get)
    Set和Collection拥有一模一样的接口。
    
    Map用 put(k,v) / get(k),还可以使用containsKey()/containsValue()来检查其中是否含有某个key/value。    

    Map中元素,可以将key序列、value序列单独抽取出来。
    使用keySet()抽取key序列,将map中的所有keys生成一个Set。
    使用values()抽取value序列,将map中的所有values生成一个Collection。
    为什么一个生成Set,一个生成Collection?那是因为,key总是独一无二的,value允许重复。
    
    HashMap会利用对象的hashCode来快速找到key
    哈希码是将对象的信息经过一些转变形成一个独一无二的int值,这个值存储在一个array中。
    我们都知道所有存储结构中,array查找速度是最快的。所以,可以加速查找。
    发生碰撞时,让array指向多个values。即,数组每个位置上又生成一个链表

posted @ 2016-01-31 01:03  wifix  阅读(313)  评论(0编辑  收藏  举报