zoukankan      html  css  js  c++  java
  • 集合框架略读

    ArrayList
    就是一个数组
    ArrayList底层以数组实现,是一种随机访问模式,再加上它实现了RandomAccess接口,因此查找也就是get的时候非常快
    ArrayList在顺序添加一个元素的时候非常方便,只是往数组里面添加了一个元素而已
    插入元素,删除元素, 会全部复制
    因此,ArrayList比较适合顺序添加、随机访问的场景。
    ArrayList transient Object[] elementData; 继承Serializable 但又不让elementData 序列化
    因为有可能elementData没装满的话,会浪费 所以

    private void writeObject(java.io.ObjectOutputStream s)
    throws java.io.IOException{
    // Write out element count, and any hidden stuff
    int expectedModCount = modCount;
    s.defaultWriteObject();
    // Write out array length
    s.writeInt(elementData.length);
    // Write out all elements in the proper order.
    for (int i=0; i<size; i++)
    s.writeObject(elementData[i]);
    if (modCount != expectedModCount) {
    throw new ConcurrentModificationException();
    }
    }


    每次序列化的时候调用这个方法,先调用defaultWriteObject()方法序列化ArrayList中的非transient元素,elementData不去序列化它,然后遍历elementData,只序列化那些有的元素
    ArrayList和Vector的区别
    Vector 线程安全的 Collections.synchronizedList(list)
    LinkList
    就是一个双向链表 Node(item, first,next) 删除插入就是断开重连很快,
    LinkList 和 ArrayList 对比 ArrayList add快 查找速度 LinkeList 寻找慢 添加快

    CopyOnWriteArrayList 是concurrent下的类 线程安全的 任何可变的操作(add、set、remove等等)都是伴随复制这个动作的
    set 时加了锁 并且操作的是volatile 可见不可改 CopyOnWriteArrayList适用于读操作远多于修改操作的并发场景中。

    Hash'Map
    内部存的是Node hash值相同值不同时,就串在后面
    HashMap的table为什么是transient的 计算hashcode调用底层系统,所以每个机器计算不同
    为了避免这一点,Java采取了重写自己序列化table的方法,在writeObject选择将key和value追加到序列化的文件最后面

    private void writeObject(java.io.ObjectOutputStream s)throws IOException {
      int buckets = capacity();
    // Write out the threshold, loadfactor, and any hidden stuff
      s.defaultWriteObject();
      s.writeInt(buckets);
      s.writeInt(size);
      internalWriteEntries(s);
    }
    void internalWriteEntries(java.io.ObjectOutputStream s) throws IOException {
      Node<K,V>[] tab;
      if (size > 0 && (tab = table) != null) {
        for (int i = 0; i < tab.length; ++i) {
          for (Node<K,V> e = tab[i]; e != null; e = e.next) {
            s.writeObject(e.key);
            s.writeObject(e.value);
            }
         }
      }
    }


    ConcurrentHashMap HashMap和Hashtable的区别 Hashtable 枷锁了 底层存的Entry 不能空value

    LinkedHashMap 继承自HashMap put 模板方法 实现了 afterNodeAccess 有序的
    桶上分配照样 但是每个会按照Linklist 存入前后地址
    每次访问一个元素(get或put),被访问的元素都被提到最后面去了
    LRU (LRU即Least Recently Used,最近最少使用)  LRUCache实现缓存LRU功能都是源自LinkedHashMap的。accessOrder afterNodeAccess 

      static final class Cache {
            private LinkedHashMap<String, CacheEntry> cache;
            private Type type;
    
            enum Type {Positive, Negative};
        public LinkedHashMap(int initialCapacity,
                             float loadFactor,
                             boolean accessOrder) {
            super(initialCapacity, loadFactor);
            this.accessOrder = accessOrder;
        }

    accessOrder  默认是false

    (1)false,所有的Entry按照插入的顺序排列

    (2)true,所有的Entry按照访问的顺序排列

      第二点的意思就是,如果有1 2 3这3个Entry,那么访问了1,就把1移到尾部去,即2 3 1。每次访问都把访问的那个数据移到双向队列的尾部去,那么每次要淘汰数据的时候,双向队列最头的那个数据不就是最不常访问的那个数据了吗?换句话说,双向链表最头的那个数据就是要淘汰的数据。

      public V get(Object key) {
            Node<K,V> e;
            if ((e = getNode(hash(key), key)) == null)
                return null;
            if (accessOrder)  // true
                afterNodeAccess(e);
            return e.value;
        }
        void afterNodeAccess(Node<K,V> e) { // move node to last
            LinkedHashMap.Entry<K,V> last;
            if (accessOrder && (last = tail) != e) {
                LinkedHashMap.Entry<K,V> p =
                    (LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;
                p.after = null;
                if (b == null)
                    head = a;
                else
                    b.after = a;
                if (a != null)
                    a.before = b;
                else
                    last = b;
                if (last == null)
                    head = p;
                else {
                    p.before = last;
                    last.after = p;
                }
                tail = p;
                ++modCount;
            }
        }
    afterNodeAccess
  • 相关阅读:
    part11-1 Python图形界面编程(Python GUI库介绍、Tkinter 组件介绍、布局管理器、事件处理)
    part10-3 Python常见模块(正则表达式)
    Cyclic Nacklace HDU
    模拟题 Right turn SCU
    状态DP Doing Homework HDU
    Dp Milking Time POJ
    区间DP Treats for the Cows POJ
    DP Help Jimmy POJ
    Dales and Hills Gym
    Kids and Prizes Gym
  • 原文地址:https://www.cnblogs.com/mxz1994/p/9332269.html
Copyright © 2011-2022 走看看