[Java]Collection总结

来源:互联网 发布:手机淘宝怎么放优惠券 编辑:程序博客网 时间:2024/06/12 07:00

已实现的具体类

  • Collection

    • List
      • ArrayList
        • public class ArrayList<E> extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, java.io.Serializable
        • 线程不安全。数组实现,查询操作快。在插入时若容量不足时的扩容和除末尾位置外的结构修改操作时需要移动元素,结构操作慢。可有重复值、null值。由于实现了RandomAcess接口,在循环中访问元素提供比通过迭代器访问更高的性能。
      • LinkedList
        • public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable
        • 线程不安全。ArrayList的双向链表实现,只需改变前区后继的引用即可完成添加删除操作,结构操作快。实现了Deque接口,添加了队列风格的操作方法。又实现了栈风格的操作方法。可有重复、null值,查询操作较ArrayLi慢。特殊的提供了一个倒序迭代器。
      • Vector
        • public class Vector<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable,
          java.io.Serializable
        • 线程安全。ArrayList的线程安全版本,由于添加了同步操作,性能较ArrayList弱些。
      • Stack
        • public class Stack<E> extends Vector<E>
        • 线程安全。继承自Vector,添加了栈风格的操作方法和search(Object o)返还o的索引若不存在返还-1、empty()判断Stack是否为空。
    • Set
      • TreeSet
        • public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, java.io.Serializable
        • 线程不安全。内部使用TreeMapkey部分储存元素,除序列化方法和NavigableSet的方法外,对TreeSet的方法调用,最终都是调用TreeMap的方法实现的。
      • HashSet
        • public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable
        • 线程不安全。内部使用HashMapkey部分储存元素,除序列化方法,对HashSet的方法调用,最终都是调用HashMap的方法实现的。除此之外,在HashSet中有个特殊的构造器HashSet(int initialCapacity, float loadFactor, boolean dummy)是一个包访问权限的方法有三个参数,该方法创建了一个LinkedHashMap<E>对象而不是HashMap<E>对象。
      • LinkedHashSet
        • public class LinkedHashSet<E> extends HashSet<E> implements Set<E>, Cloneable, java.io.Serializable
        • 线程不安全。继承自HashSet,内部仅有4个构造器,都是通过调用HashSet的那个特殊构造器实现的。
      • 所有的Set实现类都通过相应的Map实现类实现,使用Map的key值储存元素,而所有value都指向一个Objeect对象,相应的特性也来自于对应的Map实现类。
  • Map

    • TreeMap
      • public class TreeMap<K,V> extends AbstractMap<K,V> implements NavigableMap<K,V>, Cloneable, java.io.Serializable
      • 线程不安全。使用红黑树实现。所储存的元素对象必须实现了Comparable接口,用于对元素的排序。内部有个static final class Entry<K,V> implements Map.Entry<K,V>,即红黑树中的节点,与Map.Entry<K,V>相比多了表示左右节点的引用、代表颜色的字段,key值不能重复。红黑树能做的操作,TreeMap都有。
    • HashMap
      • public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable
      • 线程不安全。使用位桶+链表模型。Entry<K,V>[] table用来充当bucked,capaticy指bucked的容量,而loadFactor指bucked填充的最大比例,当bucked所用的容量大于capacity*loadFactor时,就需要对bucked进行扩容,容量为原先的两倍,扩容时会对原先的bucked进行重新分配。HashMap所用的节点也是继承自Map.Entry<K,W>, 与父类相比多了Entry<K,V> nextint hash两个字段,hash用于储存k的hash值,而next是用来创建单向链表。再算出buckedIndex后,若table[buckedIndex]==null,即这个buck是个空的,这时就直接赋值就行,若table[buckedIndex]!=null,说明这个bucked已经存有键值对了,这时就要遍历bucked上的链表找到与插入键值对的keyhash都相等的键值对,找到了就更新那个键值对的value,没有找到就在这个bucked中的链表上加上这个键值对。HashMap规定table[0]用于储存key为null的键值对。在JDK8中对HashMap有了进一步优化,当bucked中的链表长度大于等于8时,会将简单的链表调整成红黑树。
    • LinkedHashMap
      • public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V>
      • 线程不安全。继承自HashMap<K,V>LinkedHashMap<K,V>HashMap基础上添加了对插入键值对前后顺序信息的储存,多了双向链表头header和是否有序的标记accessOrder,通过在Map.Entry<K,V>中添加指向前后的引用使键值对形成双向链表以储存插入顺序。LinkedHashMap的accessOreder只有在构造器中传入true时创建出的LinkedHashMap才是有序的,其它构造器都是默认无序的。

相关接口

  • 接口Conllection<E>
    • 接口List<E>:列表,添加了依据索引设置或获取元素、查询某个元素的索引、获取通过引用实现的子列表、获取列表迭代器等操作。
    • 接口Set<E>:集合,和接口Conllection一模一样。这个接口代表了对数学集合的抽象。Set中不能有重复的值,即对任意两个Set中的对象o_1o_2不能有o_1.equals(o_2) == true。Set对象自身不能成为Set的元素。Set中能不能有null得看具体实现。
      • 接口SortedSet<E>:在Set的基础上添加了Comparator<? super E>comparator()SortedSet<E> subSet(E fromElement, E toElement)SortedSet<E> headSet()SortedSet<E> tailSet()E first()E last()等与排序相关的方法
        • 接口NavigableSet<E>:在接口SortedSet上,添加了E lower(E e)E floor(E e)E ceiling(E e)E higher(E e)等获取Set中e元素左右两侧的极值;E pollFirst()E pollLast()等获取Set中的极值;以及反向Set的元素视图。
  • 接口Map<K,V>:映射表或散列表,一个键值对<K,V>,K与V一一对应,K不重复。在接口内部还有一个内部接口Entry<K,V>,即对键值对的相关操作。

    • SortedMap<K,V>:在Map<K,V>基础上添加了排序的功能,添加的内容与SortedSet相对Set<E>的添加内容相似。
      • NavigableMap<K,V>:在SortedMap<K,V>基础上添加了对k<k,v>排序的功能,添加的内容与NavigableSet<E>相对SortedSet<E>的添加内容相似。
  • 接口RandomAccess:随机访问,是一个标记接口,用于表明该类支持依据索引快速随机访问(List的所有实现类都是) 。

    ArrayList<Integer> list = new ArrayList<>();for (int i=0, n=list.size(); i < n; i++)    list.get(i);

    当list.size()越大,上面的越明显快于下面的。

    for (Iterator i=list.iterator(); i.hasNext();)    i.next();
  • 接口Iterable<E>:只有一个方法Iterator<E> iterator()。要想为类提供迭代功能,首先实现Iterator<E> iterator()方法,用它来返回一个迭代器对象。然后为了返回迭代器对象,就需要在类中创建一个接口Iterator<E>的实现类,在Interator<E> iterator()方法中只要创建这个类的一个实例再返回就行了。Iterator<E>接口有三个方法boooean hasNext()E next()void remove()

关于迭代器

  迭代器Iterator的fast-fail:在集合中有个modCount,集合的每次结构操作(添加元素,删除元素)都会使modCount加1。在创建迭代器时会有int expectedModCount = modCount,即储存迭代器创建时的modCount值。对迭代器的每一次方法调用,迭代器都会检查expectedModCount == modCount,一旦程序在迭代的过程中在另一处改变了集合的结构导致expectedModCount不等于modCount,就会导致迭代停止,并抛出ConcurrentModificationException异常。当然对迭代器调用remove()时,迭代器会更新expectedModCount的值,即expectedModCount = modCount。因此在线程不安全中迭代器迭代时,只能用迭代器的remove>()删除某元素,其它方法是不可行的。在线程安全的集合中所有结构操作都实现了同步,且迭代器迭代会获取对象锁,所有不会有这个问题。

  列表迭代器ListIterator继承自Iterator,添加了hasPrevious()previous()perviousIndex()set()add()等方法。

关于hashCode():

  • Stringhashcode()

    public int hashCode() {    int h = hash;//默认值为0    if (h == 0 && value.length > 0) {        char val[] = value;//String储存字符串的字符数组,private final char value[]        for (int i = 0; i < value.length; i++) {            h = 31 * h + val[i];        }        hash = h;    }    return h;}
  • 其它类如果没有重载hashCode(),就会调用Object的本地方法public native int hashCode()

  • HashSet的重复判断和HashMapKey值比较都会运用到对象的hashCode()方法,如果想要自定义这种行为,可以通过重载hashCode()方法来实现。
0 0
原创粉丝点击