zoukankan      html  css  js  c++  java
  • java 集合类

        为了保存数目不确定的对象,JDK中提供了集合类(又称容器类),这些类可以存储任意类型的对象,并且长度可变,所有的集合类都位于java.util包中,在使用时需要导入该包,否则会出现异常。

    Java集合类

    集合按照存储结构可以分为两大类,分别是单列集合(Collection)双列集合(Map),这两种集合的特点如下所示:

    • Collection:单列集合类的根接口,用于存储一系列符合某种规则的元素,它有两个重要的子接口,分别是List和Set。其中,List的特点是元素有序,元素可重复;Set的特点是元素无序,而且不可重复。List接口的实现类有ArrayList和LinkedList,Set接口的主要实现类有HashSet环绕TreeSet。
    • Map:双列集合类的根接口,用于存储具有键(Key)、值(Value)映射关系的元素,每个元素都包含一对键值,在使用Map集合时可以通过指定的key找到对应的Value。Map接口的主要实现类有HashMap和TreeMap。 

    List接口                                                                                                                             

      在List集合中可以出现相同的元素,所有的元素是以一种线性方式进行存储的,因此使用此集合能够精确地控制每个元素插入的位置,用户能够使用索引访问List中的元素。另外,List集合还有一个特点就是元素有序,即元素的存入和取出顺序一致。

    ArrayList集合

      ArrayList 是一个数组队列,相当于 动态数组。与Java中的数组相比,它的容量能动态增长。它继承于AbstractList,实现了List, RandomAccess, Cloneable, java.io.Serializable这些接口。

      ArrayList 继承了AbstractList,实现了List。它是一个数组队列,提供了相关的添加、删除、修改、遍历等功能。
      ArrayList 实现了RandmoAccess接口,即提供了随机访问功能RandmoAccess是java中用来被List实现,为List提供快速访问功能的。在ArrayList中,我们即可以通过元素的序号快速获取元素对象;这就是快速随机访问。

      ArrayList 实现了Cloneable接口,即覆盖了函数clone(),能被克隆。

      ArrayList 实现java.io.Serializable接口,这意味着ArrayList支持序列化,能通过序列化去传输。

     和Vector不同,ArrayList中的操作不是线程安全的!所以,建议在单线程中才使用ArrayList,而在多线程中可以选择Vector或者CopyOnWriteArrayList。

    ArrayList的继承关系

    java.lang.Object
       ↳     java.util.AbstractCollection<E>
             ↳     java.util.AbstractList<E>
                   ↳     java.util.ArrayList<E>
    
    public class ArrayList<E> extends AbstractList<E>
            implements List<E>, RandomAccess, Cloneable, java.io.Serializable {}

    ArrayList API

     1 // Collection中定义的API
     2 boolean             add(E object)
     3 boolean             addAll(Collection<? extends E> collection)
     4 void                clear()
     5 boolean             contains(Object object)
     6 boolean             containsAll(Collection<?> collection)
     7 boolean             equals(Object object)
     8 int                 hashCode()
     9 boolean             isEmpty()
    10 Iterator<E>         iterator()
    11 boolean             remove(Object object)
    12 boolean             removeAll(Collection<?> collection)
    13 boolean             retainAll(Collection<?> collection)
    14 int                 size()
    15 <T> T[]             toArray(T[] array)
    16 Object[]            toArray()
    17 // AbstractCollection中定义的API
    18 void                add(int location, E object)
    19 boolean             addAll(int location, Collection<? extends E> collection)
    20 E                   get(int location)
    21 int                 indexOf(Object object)
    22 int                 lastIndexOf(Object object)
    23 ListIterator<E>     listIterator(int location)
    24 ListIterator<E>     listIterator()
    25 E                   remove(int location)
    26 E                   set(int location, E object)
    27 List<E>             subList(int start, int end)
    28 // ArrayList新增的API
    29 Object               clone()
    30 void                 ensureCapacity(int minimumCapacity)
    31 void                 trimToSize()
    32 void                 removeRange(int fromIndex, int toIndex)
    ArrayList API

    ArrayList的toArray

      ArrayList提供了一个将List转为数组的一个非常方便的方法toArray。toArray有两个重载的方法:

      (1)list.toArray();

      (2)list.toArray(T[]  a);

      对于第一个重载方法,是将list直接转为Object[] 数组;

      第二种方法是将list转化为你所需要类型的数组,当然我们用的时候会转化为与list内容相同的类型。

     ArrayList 三种遍历方式

      (1)第一种,通过迭代器遍历。即通过Iterator去遍历。

    Integer value = null;
    Iterator iter = list.iterator();
    while (iter.hasNext()) {
        value = (Integer)iter.next();
    }

      (2) 第二种,随机访问,通过索引值去遍历。
    由于ArrayList实现了RandomAccess接口,它支持通过索引值去随机访问元素。

    Integer value = null;
    int size = list.size();
    for (int i=0; i<size; i++) {
        value = (Integer)list.get(i);        
    }

      (3)第三种,foreach循环遍历。如下:

    Integer value = null;
    for (Integer integ:list) {
        value = integ;
    }

     使用随机访问(即,通过索引序号访问)效率最高,而使用迭代器的效率最低

    Set接口                                                                                                                                 

      Set接口主要有两个实现类,分别是HashSet和TreeSet。其中,HashSet是根据对象的哈希值确定元素在集合中的存储位置,因此具有良好的存取和查找性能。TreeSet是以二叉排序树的方式存储元素,他可以实现对几个元素进行排序。

    HashSet集合

      HashSet结合之所以能确保不出现重复的元素,是因为在想Set中添加对象时,会西安调用次对象所在类的hashCode()方法,计算此对象的哈希值,次哈希值决定了此对象在Set中的存储对象,再通过equals()比较这两个对象是否相同,如果相同,则后一个对象就不能再添加进来。

    Map接口                                                                                                                              

     HashMap集合

      HashMap集合是基于哈希表的Map接口的实现,它用于存储键值映射关系,但不保证映射的顺序。

      HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。

      HashMap 继承于AbstractMap,实现了Map、Cloneable、java.io.Serializable接口
      HashMap 的实现不是同步的,这意味着它不是线程安全的。它的key、value都可以为null。此外,HashMap中的映射不是有序的。

      HashMap 的实例有两个参数影响其性能:“初始容量” 和 “加载因子”。容量 是哈希表中桶的数量,初始容量 只是哈希表在创建时的容量。加载因子 是哈希表在其容量自动增加之前可以达到多满的一种尺度。当哈希表中的条目数超出了加载因子与当前容量的乘积时,则要对该哈希表进行 rehash 操作(即重建内部数据结构),从而哈希表将具有大约两倍的桶数。
      通常,默认加载因子是 0.75, 这是在时间和空间成本上寻求一种折衷。加载因子过高虽然减少了空间开销,但同时也增加了查询成本(在大多数 HashMap 类的操作中,包括 get 和 put 操作,都反映了这一点)。在设置初始容量时应该考虑到映射中所需的条目数及其加载因子,以便最大限度地减少 rehash 操作次数。如果初始容量大于最大条目数除以加载因子,则不会发生 rehash 操作。

    HashMap的继承关系

    java.lang.Object
       ↳     java.util.AbstractMap<K, V>
             ↳     java.util.HashMap<K, V>
    
    public class HashMap<K,V>
        extends AbstractMap<K,V>
        implements Map<K,V>, Cloneable, Serializable { }

     (01) HashMap继承于AbstractMap类,实现了Map接口。Map是"key-value键值对"接口,AbstractMap实现了"键值对"的通用函数接口。 
    (02) HashMap是通过"拉链法"实现的哈希表。它包括几个重要的成员变量:table, size, threshold, loadFactor, modCount。
      table是一个Entry[]数组类型,而Entry实际上就是一个单向链表。哈希表的"key-value键值对"都是存储在Entry数组中的。 
      size是HashMap的大小,它是HashMap保存的键值对的数量。 
      threshold是HashMap的阈值,用于判断是否需要调整HashMap的容量。threshold的值="容量*加载因子",当HashMap中存储数据的数量达到threshold时,就需要将HashMap的容量加倍。
      loadFactor就是加载因子。 
      modCount是用来实现fail-fast机制的。

    HashMap的整体结构

    简单来说,HashMap由数组+链表组成的,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的,如果定位到的数组位置不含链表(当前entry的next指向null),那么对于查找,添加等操作很快,仅需一次寻址即可;如果定位到的数组包含链表,对于添加操作,其时间复杂度为O(n),首先遍历链表,存在即覆盖,否则新增;对于查找操作来讲,仍需遍历链表,然后通过key对象的equals方法逐一比对查找。所以,性能考虑,HashMap中的链表出现越少,性能才会越好。

     HashMap遍历方式

      (1) 遍历HashMap的键值对

    第一步:根据entrySet()获取HashMap的“键值对”的Set集合。
    第二步:通过Iterator迭代器遍历“第一步”得到的集合。

     1 // 假设map是HashMap对象
     2 // map中的key是String类型,value是Integer类型
     3 Integer integ = null;
     4 Iterator iter = map.entrySet().iterator();
     5 while(iter.hasNext()) {
     6     Map.Entry entry = (Map.Entry)iter.next();
     7     // 获取key
     8     key = (String)entry.getKey();
     9         // 获取value
    10     integ = (Integer)entry.getValue();

      (2)遍历HashMap的键

    第一步:根据keySet()获取HashMap的“键”的Set集合。
    第二步:通过Iterator迭代器遍历“第一步”得到的集合。

    // 假设map是HashMap对象
    // map中的key是String类型,value是Integer类型
    String key = null;
    Integer integ = null;
    Iterator iter = map.keySet().iterator();
    while (iter.hasNext()) {
            // 获取key
        key = (String)iter.next();
            // 根据key,获取value
        integ = (Integer)map.get(key);

      (3)遍历HashMap的值

    第一步:根据value()获取HashMap的“值”的集合。
    第二步:通过Iterator迭代器遍历“第一步”得到的集合。

    // 假设map是HashMap对象
    // map中的key是String类型,value是Integer类型
    Integer value = null;
    Collection c = map.values();
    Iterator iter= c.iterator();
    while (iter.hasNext()) {
        value = (Integer)iter.next();
    }

    Properties集合

      Properties主要用于存储字符串类型的键和值,由于Properties类实现了Map接口,因此,Properties类本质上是一种简单的Map集合。在实际开发中,经常使用Properties几个存取应用的配置项。

    (1)setProperty ( String key, String value) ,调用 Hashtable 的方法 put 。他通过调用基类的put方法来设置 键 - 值对。

    (2)getProperty ( String key),用指定的键在此属性列表中搜索属性。也就是通过参数 key ,得到 key 所对应的 value。

    (3) load ( InputStream inStream),从输入流中读取属性列表(键和元素对)。通过对指定的文件进行装载来获取该文件中的所有键 - 值对。以供 getProperty ( String key) 来搜索。

    (4)store ( OutputStream out, String comments),以适合使用 load 方法加载到 Properties 表中的格式,将此 Properties 表中的属性列表(键和元素对)写入输出流。与 load 方法相反,该方法将键 - 值对写入到指定的文件中去。

    (5) clear (),清除所有装载的 键 - 值对。该方法在基类中提供。

    Collection 和 Collections的区别:

      Collection是一个集合的接口。它提供了对集合对象进行基本操作的通用方法。实现该接口的类主要有List和Set,该接口的设计目标是为各种具体的集合提供最大化的同一操作方式。

      Collections是针对集合类的一个包装类,它提供了一系列静态方法实现对各种集合的搜索、排序以及线程安全等操作,其中大部分方法用于处理线性表。Collection类不能实例化,如同一个工具类,服务于Collection框架。如果在使用Collections类的方法时,对用Collection的对象null,则这些方法都会抛出NullPointException。

    参考:

    http://www.cnblogs.com/skywang12345/p/3308556.html

    http://www.cnblogs.com/skywang12345/p/3310835.html

    https://www.cnblogs.com/chengxiao/p/6059914.html

    2018-10-03 20:46:17

  • 相关阅读:
    链式编程思想
    iOS开发:后台运行以及保持程序在后台长时间运行
    iOS懒加载
    mysql命令行的一些小技巧【实用:多屏显示,格式化输出等】
    iOS UITextField实时监听获取输入内容,中文状态去除预输入拼音字符
    'vector' file not found错误解决 && xcode archive 去掉dsym文件和添加dsym文件
    iOS APP 中H5视频默认全屏播放问题解决
    Sublime Text 3 插件的安装、升级和卸载,以及安装package control 出现问题解决过程记录
    ES5和ES6对象导出和导入(转载,待整理)
    react/React Native 在 import 导入时,有的带花括号{},有的不带原理解析
  • 原文地址:https://www.cnblogs.com/qqiua/p/9740734.html
Copyright © 2011-2022 走看看