国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频

從源碼分析面試中經(jīng)常出現(xiàn)的集合類問題

共 50791字,需瀏覽 102分鐘

 ·

2021-03-26 10:42

                                    點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號”

優(yōu)質(zhì)文章,第一時間送達(dá)

76套java從入門到精通實(shí)戰(zhàn)課程分享



Collection接口

/* @author  Josh Bloch
 * @author  Neal Gafter
 * @see     Set
 * @see     List
 * @see     Map
 * @see     SortedSet
 * @see     SortedMap
 * @see     HashSet
 * @see     TreeSet
 * @see     ArrayList
 * @see     LinkedList
 * @see     Vector
 * @see     Collections
 * @see     Arrays
 * @see     AbstractCollection
 * @since 1.2
    集合層次結(jié)構(gòu)中的根接口。集合表示一組對象,稱為其元素。
    一些集合允許重復(fù)的元素,而另一些則不允許。有些是有序的,而另一些則是無序的。 
    JDK不提供此接口的任何直接實(shí)現(xiàn):它提供了更多特定子接口的實(shí)現(xiàn)
 */
public interface Collection<E> extends Iterable<E> {
    // Query Operations
    /**
    返回此集合中的元素數(shù)
     */
    int size();
    /**
   如果此集合不包含任何元素,則返回<tt> true </ tt>
     */
    boolean isEmpty();
    ...........
        .........

Collection接口是集合類的根接口,繼承了Iterable接口,Java中沒有直接提供Collection接口的實(shí)現(xiàn)類。但是卻產(chǎn)生了兩個接口,就是Set和List。Set中不能包含重復(fù)的元素。List是一個有序的集合,可以包含重復(fù)的元素,提供了按索引訪問的方式


List接口

1、List(有序、可重復(fù))

List里存放的對象是有序的,同時也是可以重復(fù)的,List關(guān)注的是索引,擁有一系列和索引相關(guān)的方法,查詢速度快。因?yàn)橥鵯ist集合里插入或刪除數(shù)據(jù)時,會伴隨著后面數(shù)據(jù)的移動,所有插入刪除數(shù)據(jù)速度慢。

2、Set(無序、不能重復(fù))

Set里存放的對象是無序,不能重復(fù)的,集合中的對象不按特定的方式排序,只是簡單地把對象加入集合中。

 /* @see Collection
 * @see List
 * @see SortedSet
 * @see HashSet
 * @see TreeSet
 * @see AbstractSet
 * @see Collections#singleton(java.lang.Object)
 * @see Collections#EMPTY_SET
 * @since 1.2
     不包含重復(fù)元素的集合
 */
public interface Set<E> extends Collection<E> {
    // Query Operations
    /**
     返回此集合中的元素數(shù)(其基數(shù))
     */
    int size();
    /**
    如果此集合不包含任何元素,則返回<tt> true </ tt>
     */
    boolean isEmpty();
    /**
    如果此集合包含指定的元素,則返回<tt> true </ tt>
     */
    boolean contains(Object o);
    /**
   返回此集合中元素的迭代器。 *元素以不特定的順序返回(除非此集合是提供保證的某些*類的實(shí)例)。
     */
    Iterator<E> iterator();
    ...........
        .........

ArrayList(動態(tài)數(shù)組)

List接口的可調(diào)整大小的數(shù)組實(shí)現(xiàn)。實(shí)現(xiàn)所有可選的列表操作(實(shí)現(xiàn)了List的全部方法),并允許所有元素,包括null;

/* @see     Collection
 * @see     List
 * @see     LinkedList
 * @see     Vector
 * @since   1.2
  List接口的可調(diào)整大小的數(shù)組實(shí)現(xiàn)。實(shí)現(xiàn)所有可選的列表操作,并允許所有元素,包括null。除了實(shí)現(xiàn) List接口之外,此類還提供了一些方法來操縱內(nèi)部用于存儲列表的數(shù)組的大小
 */

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
    private static final long serialVersionUID = 8683452581122892189L;
    /**
       默認(rèn)初始容量
     */
    private static final int DEFAULT_CAPACITY = 10;

    /**
    用于空實(shí)例的共享空數(shù)組實(shí)例
     */
    private static final Object[] EMPTY_ELEMENTDATA = {};

    /**
    共享的空數(shù)組實(shí)例,用于默認(rèn)大小的空實(shí)例。我們將其與EMPTY_ELEMENTDATA區(qū)別開來,以了解添加第一個元素時需要充氣多少
     */
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
      /**
    用于存儲ArrayList元素的數(shù)組緩沖區(qū)。ArrayList的容量是此數(shù)組緩沖區(qū)的長度。添加第一個元素時,任何具有elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA的空ArrayList都將擴(kuò)展為DEFAULT_CAPACITY,
    該elementData是真正存放元素的容器,可見ArrayList是基于數(shù)組實(shí)現(xiàn)的;
     */
    transient Object[] elementData; //非私有,以簡化嵌套類的訪問


  • ArrayList提供了三個構(gòu)造方法


    /** *構(gòu)造一個具有指定初始容量的空列表。 @param initialCapacity列表的初始容量@如果指定的初始容量為負(fù),則拋出IllegalArgumentException */
    public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }
      /** *構(gòu)造一個初始容量為10的空列表。 */
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

    /**構(gòu)造一個包含指定集合的元素的列表,其順序由集合的迭代器返回。  @param c 要將其元素放入此列表的集合如果指定的集合為null,則拋出NullPointerException */
    public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray();
        if ((size = elementData.length) != 0) {
            // c.toArray might (incorrectly) not return Object[] (see 6260652)
            if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else {
            // replace with empty array.
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }

ArrayList擴(kuò)容和add,set等方法

可見當(dāng)初始化的list是一個空ArrayList的時候,會直接擴(kuò)容到DEFAULT_CAPACITY,該值大小是一個默認(rèn)值10。而當(dāng)添加進(jìn)ArrayList中的元素超過了數(shù)組能存放的最大值就會進(jìn)行擴(kuò)容。

    /**  ArrayList擴(kuò)容
    默認(rèn)初始容量  DEFAULT_CAPACITY = 10
     */
private static int calculateCapacity(Object[] elementData, int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        return minCapacity;
    }

  • get,add,set等方法

   /** *返回此列表中指定位置的元素。@要返回的元素的索引索引 @返回此列表中指定位置的元素、@throws IndexOutOfBoundsException {@inheritDoc} */
    public E get(int index) {
        rangeCheck(index);

        return elementData(index);
    }

    /**
     用指定的元素替換此列表中指定位置的元素。@param要替換元素的索引index @param要存儲在指定位置的元素 @返回先前在指定位置的元素 @throws IndexOutOfBoundsException {@inheritDoc}
     */
    public E set(int index, E element) {
        rangeCheck(index);

        E oldValue = elementData(index);
        elementData[index] = element;
        return oldValue;
    }

    /**
   將指定的元素追加到此列表的末尾。@要附加到此列表的參數(shù)元素 @返回 true (由{@link Collection#add}指定)
     */
    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }


LinkedList(雙向鏈表)

LinkedList是一種鏈表結(jié)構(gòu),從UML圖可以看到,LinkList接口實(shí)現(xiàn)了Queue接口和List接口

  • 進(jìn)LinkList源碼看看


List和Deque接口的雙鏈列表實(shí)現(xiàn)。實(shí)現(xiàn)所有可選的列表操作(實(shí)現(xiàn)了List的全部方法),并允許所有元素(包括null)


LinkedList由一個頭節(jié)點(diǎn)和一個尾節(jié)點(diǎn)組成,分別指向鏈表的頭部和尾部。


/** {@code List}和{@code Deque}接口的雙鏈列表實(shí)現(xiàn)。實(shí)現(xiàn)所有可選的列表操作,
并允許所有元素(包括{@code null})。
所有操作均按雙鏈接列表的預(yù)期執(zhí)行。索引到列表中的操作將從開頭或結(jié)尾遍歷列表,
以更接近指定索引的位置為準(zhǔn)。
*/

public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
    transient int size = 0;

    /**
     指向第一個節(jié)點(diǎn)的指針
     * Invariant: (first == null && last == null) ||
     *            (first.prev == null && first.item != null)
     */
    transient Node<E> first;

    /**
     指向最后一個節(jié)點(diǎn)的指針
     * Invariant: (first == null && last == null) ||
     *            (last.next == null && last.item != null)
     */
    transient Node<E> last;

    /**
     構(gòu)造一個空List
     */
    public LinkedList() {
    }

    /**
   構(gòu)造一個包含指定集合的元素的List,其順序由集合的迭代器返回。
   @param c 要將其元素放入此List的集合
   如果指定的集合為null,則拋出NullPointerException
     */
    public LinkedList(Collection<? extends E> c) {
        this();
        addAll(c);
    }
    /** Node節(jié)點(diǎn)*/
      private static class Node<E> {
        E item;
        Node<E> next;
        Node<E> prev;

        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }
}

  • 數(shù)據(jù)結(jié)構(gòu)中鏈表的頭插法linkFirst和尾插法linkLast

 /**
     * Links e as last element.
     */
    void linkLast(E e) {
        final Node<E> l = last;
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
    }

    /**
     * Inserts element e before non-null Node succ.
     */
    void linkBefore(E e, Node<E> succ) {
        // assert succ != null;
        final Node<E> pred = succ.prev;
        final Node<E> newNode = new Node<>(pred, e, succ);
        succ.prev = newNode;
        if (pred == null)
            first = newNode;
        else
            pred.next = newNode;
        size++;
        modCount++;
    }

  • LinkList的查詢方法

 

  /**
    返回此列表中指定位置的元素,要遍歷,找到節(jié)點(diǎn)才能拿到元素
     */
    public E get(int index) {
        checkElementIndex(index);
        return node(index).item;
    }

/**返回指定元素索引處的(非空)節(jié)點(diǎn) */  
Node<E> node(int index) {
        // assert isElementIndex(index);
        if (index < (size >> 1)) {
            Node<E> x = first;
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
        } else {
            Node<E> x = last;
            for (int i = size - 1; i > index; i--)
                x = x.prev;
            return x;
        }
    }

注意!ArrayList隨機(jī)訪問比LinkedList快的原因,LinkedList要遍歷找到該位置才能進(jìn)行修改,而ArrayList是內(nèi)部數(shù)組操作會更快


(1)ArrayList是實(shí)現(xiàn)了基于動態(tài)數(shù)組的數(shù)據(jù)結(jié)構(gòu),LinkedList基于鏈表的數(shù)據(jù)結(jié)構(gòu)。

(2)對于隨機(jī)訪問get和set,ArrayList覺得優(yōu)于LinkedList,因?yàn)長inkedList要遍歷找節(jié)點(diǎn)。

(3)對于新增和刪除操作add和remove,LinedList比較占優(yōu)勢,因?yàn)锳rrayList要移動數(shù)據(jù)。這一點(diǎn)要看實(shí)際情況的。若只對單條數(shù)據(jù)插入或刪除,ArrayList的速度反而優(yōu)于LinkedList。但若是批量隨機(jī)的插入刪除數(shù)據(jù),LinkedList的速度大大優(yōu)于ArrayList. 因?yàn)锳rrayList每插入一條數(shù)據(jù),要移動插入點(diǎn)及之后的所有數(shù)據(jù)。


Vector

Vector類實(shí)現(xiàn)了對象的可增長數(shù)組。像數(shù)組一樣,初始數(shù)組大小為10和ArrayList相同,它包含可以使用整數(shù)索引訪問的組件。但是Vector的大小可以根據(jù)需要增大或縮小,以適應(yīng)創(chuàng)建Vector之后的添加和刪除項(xiàng);


與新的集合實(shí)現(xiàn)不同,Vector是同步的,線程安全的。如果不需要線程安全實(shí)現(xiàn),建議使用 ArrayList代替 Vector,ArrayList是線程不安全的

public class Vector<E>
    extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
    /**
  向量分量存儲在其中的數(shù)組緩沖區(qū)。
  向量的容量是此數(shù)組緩沖區(qū)的長度,
  并且至少足夠大以包含所有向量的元素。
  Vector中最后一個元素之后的所有數(shù)組元素均為null
     */
    protected Object[] elementData;
    /**
    此Vector對象中有效組件的數(shù)量
     * @serial
     */
    protected int elementCount;

    /**
   向量的容量在其大小大于其容量時自動增加的量。如果容量增量小于或等于零,
   則向量的容量每次需要增長時都會加倍。
     * @serial
     */
    protected int capacityIncrement;

    /** 使用JDK 1.0.2中的serialVersionUID來實(shí)現(xiàn)互操作性 */
    private static final long serialVersionUID = -2767605614048989439L;

    /**
     使用指定的初始容量和容量增量構(gòu)造一個空向量。 @param initialCapacity向量的初始容量
     @param Capacity增大向量溢出時容量增加的數(shù)量
     如果指定的初始容量為負(fù),則拋出IllegalArgumentException
     */
    public Vector(int initialCapacity, int capacityIncrement) {
        super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        this.elementData = new Object[initialCapacity];
        this.capacityIncrement = capacityIncrement;
    }
    /**
   構(gòu)造一個具有指定初始容量和*容量增量等于零的空向量。
   @param initialCapacity向量的初始容量
   @如果指定的initialCapacity為負(fù),則拋出IllegalArgumentException
     */
    public Vector(int initialCapacity) {
        this(initialCapacity, 0);
    }
    /**
    構(gòu)造一個空向量,以便其內(nèi)部數(shù)據(jù)數(shù)組的大小為 10,并且其標(biāo)準(zhǔn)容量增量為零
     */
    public Vector() {
        this(10);
    }
    /**
   構(gòu)造一個向量,該向量包含指定集合的元素,
   并按集合的迭代器返回它們的順序。
   @param c 將元素放置在此向量中的集合
   如果指定的集合為null,則拋出NullPointerException
     */
    public Vector(Collection<? extends E> c) {
        elementData = c.toArray();
        elementCount = elementData.length;
        // c.toArray might (incorrectly) not return Object[] (see 6260652)
        if (elementData.getClass() != Object[].class)
            elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
    }


為什么Vector是線程安全的?

vector是線程同步的,所以它也是線程安全的,而arraylist是線程異步的,是不安全的。如果不考慮到線程的安全因素,一般用arraylist效率比較高


  • 使用synchronized給方法加鎖,達(dá)到線程安全的目的;

 ..........
public synchronized E get(int index) {
        if (index >= elementCount)
            throw new ArrayIndexOutOfBoundsException(index);

        return elementData(index);
    }
    public synchronized E set(int index, E element) {
        if (index >= elementCount)
            throw new ArrayIndexOutOfBoundsException(index);

        E oldValue = elementData(index);
        elementData[index] = element;
        return oldValue;
    }

    public synchronized boolean add(E e) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = e;
        return true;
    }
............

ArrayList是非線程安全的,Vector是線程安全的;

HashMap是非線程安全的,HashTable是線程安全的;

StringBuilder是非線程安全的,StringBuffer是線程安全的。


Vector和ArrayList擴(kuò)容數(shù)組的區(qū)別

  • ArrayList擴(kuò)容數(shù)組1.5倍,擴(kuò)容50%;

 private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

  • Vector擴(kuò)容數(shù)組2倍,擴(kuò)容100%;

 private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                         capacityIncrement : oldCapacity);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        elementData = Arrays.copyOf(elementData, newCapacity);
    }


Set接口

Set里存放的對象是無序,不能重復(fù)的,集合中的對象不按特定的方式排序,只是簡單地把對象加入集合中。


不包含重復(fù)元素的集合


HashSet(無序)

此類實(shí)現(xiàn)由散列表(實(shí)際上是 HashMap 實(shí)例)支持的Set接口。它不保證集合的迭代順序。特別是,它不能保證順序會隨時間保持不變。此類允許null 元素


如果多個線程同時訪問哈希集,并且線程中的至少一個修改了哈希集,則它必須 </ i> >從外部進(jìn)行同步。這通常是通過對自然封裝了該集合的某個對象進(jìn)行同步來完成的。如果不存在這樣的對象,則應(yīng)使用Collections synchronized Set Collections.synchronizedSet} 方法來“包裝”該集合。最好在創(chuàng)建時完成此操作,以防止意外異步訪問集合;(說明Hashset線程不安全)


  • HashSet集合底層就是

HashMap(hashmap無序所以hashset也無序),基于二叉樹的treemap,treeset有序

public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable
{
    static final long serialVersionUID = -5024744406713321676L;
    private transient HashMap<E,Object> map;
    // Dummy value to associate with an Object in the backing Map
    private static final Object PRESENT = new Object();
    /**
     構(gòu)造一個新的空集
     支持的HashMap實(shí)例具有默認(rèn)初始容量(16)和負(fù)載因子(0.75)
     */
    public HashSet() {
        map = new HashMap<>();
    }
    /**
   構(gòu)造一個新集合,其中包含指定集合中的元素。 
  HashMap是使用默認(rèn)負(fù)載因子(0.75)和足以容納指定集合中的元素的初始容量創(chuàng)建的。 
   @param c 要將其元素放入此集合的集合
   如果指定的集合為null,則拋出NullPointerException
     */
    public HashSet(Collection<? extends E> c) {
        map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
        addAll(c);
    }

    public HashSet(int initialCapacity, float loadFactor) {
        map = new HashMap<>(initialCapacity, loadFactor);
    }

    public HashSet(int initialCapacity) {
        map = new HashMap<>(initialCapacity);
    }
    /**
   構(gòu)造一個新的空鏈接哈希集(此包private構(gòu)造函數(shù)僅由LinkedHashSet使用)
   支持 HashMap實(shí)例是具有指定的初始容量和指定的負(fù)載因子的LinkedHashMap。
   @param initialCapacity 哈希圖的初始容量
   @param loadFactor 哈希圖的負(fù)載因子
   @param dummy(將此構(gòu)造函數(shù)與其他int,float構(gòu)造函數(shù)區(qū)分開。
   @throws IllegalArgumentException如果初始容量為小于零,或者負(fù)載因子為非正
     */
    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
    }


  • HashSet怎么保證元素不重復(fù)?

  public boolean add(E e) {
        return map.put(e, PRESENT)==null;  //map元素是不重復(fù)的 后面見到HashMap
    }

  • HashSet是如何保證元素的唯一性?

//如果此集合已經(jīng)包含元素,則調(diào)用將使該集合保持不變  
public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }
------------------------------------------------------
    public V put(K key, V value) {       // HashMap中的put方法
        return putVal(hash(key), key, value, falsetrue);
    }
   /** 首先會使用 hash() 函數(shù)生成一個 int 類型的 hashCode 散列值,然后與已經(jīng)存儲的元素的 hashCode 值作比較,如果 hashCode 值不相等,則所存儲的兩個對象一定不相等,此時把這個新元素存儲在它的 hashCode 位置上;如果 hashCode 相等*/

TreeSet(有序)

基于TreeMap的NavigableSet實(shí)現(xiàn)。元素使用其{@link Comparable 自然排序}進(jìn)行排序,或通過在集合創(chuàng)建時提供的{@link Comparator}進(jìn)行排序,具體取決于所使用的構(gòu)造函數(shù)。此實(shí)現(xiàn)為基本操作({@code add},{@ code remove}和{@code contains})提供了保證的log(n)時間成本。請注意,如果要正確實(shí)現(xiàn){@code Set}接口,則集合(無論是否提供了顯式比較器)所維護(hù)的順序必須與equals 一致。

public class TreeSet<E> extends AbstractSet<E>
    implements NavigableSet<E>, Cloneable, java.io.Serializable
{
    private transient NavigableMap<E,Object> m;
    private static final Object PRESENT = new Object();
    TreeSet(NavigableMap<E,Object> m) {
        this.m = m;
    }
    /**
   構(gòu)造一個新的空樹集,并根據(jù)其元素的自然順序進(jìn)行排序。
   插入到集合中的所有元素都必須實(shí)現(xiàn){@link Comparable}接口
     */
    public TreeSet() {
        this(new TreeMap<E,Object>());
    }
    /**
   構(gòu)造一個新的空樹集,并根據(jù)指定的比較器進(jìn)行排序。
   插入到集合中的所有元素都必須由指定的比較器進(jìn)行相互比較:
   {@code比較器.compare(e1,* e2)}
     */
    public TreeSet(Comparator<? super E> comparator) {
        this(new TreeMap<>(comparator));
    }
    /**
   *構(gòu)造一個新的樹集,其中包含指定集合中的元素,并根據(jù)其元素的自然順序進(jìn)行排序。
   插入集合中的所有元素都必須實(shí)現(xiàn){@link Comparable}接口。
   此外,所有此類元素必須可相互比較:
   @param c集合,其元素將組成新集合
     */
    public TreeSet(Collection<? extends E> c) {
        this();
        addAll(c);
    }


Map接口

將鍵(key)映射到值(value)的對象。映射不能包含重復(fù)的鍵;每個鍵最多可以映射到一個值

public interface Map<K,V> {
    // Query Operations
    /**
    返回此映射中的鍵值映射數(shù)
     */
    int size();
    /**
  如果此映射不包含鍵值映射,則返回true
     */
    boolean isEmpty();
    /**
    如果此映射包含指定*鍵的映射,則返回true
     */
    boolean containsKey(Object key);
    /**
    如果此映射將一個或多個鍵映射到指定值,則返回 true 
     */
    boolean containsValue(Object value);
    /**
    返回指定鍵所映射到的值
    如果此映射不包含該鍵的映射,則返回 null
     */
    V get(Object key);

    // Modification Operations
    /**
    將指定值與此映射中的指定鍵關(guān)聯(lián)(可選操作)
    如果該映射先前包含鍵的映射,則舊值將替換為指定值
     */
    V put(K key, V value);
    /**
    從該映射中刪除鍵的映射(如果存在)
     */
    V remove(Object key);


HashMap(鏈表加數(shù)組)

HashMap是 Map 接口的基于哈希表的實(shí)現(xiàn)。HashMap提供了所有可選的映射操作,并允許 null 值和null 鍵。HashMap類與 Hashtable大致等效,除了HashMap不同步并且允許空值。)此類不保證map的順序;特別是,它不能保證順序會隨著時間的推移保持恒定;


HashMap是線程不安全的,HashTable是線程安全的


HashMap的常量組成

 //是hashMap的最小容量16,容量就是數(shù)組的大小也就是變量,
    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
    //最大數(shù)量,該數(shù)組最大值為2^31一次方。
    static final int MAXIMUM_CAPACITY = 1 << 30;
    //默認(rèn)的加載因子,如果構(gòu)造的時候不傳則為0.75
    static final float DEFAULT_LOAD_FACTOR = 0.75f;
    //一個位置里存放的節(jié)點(diǎn)轉(zhuǎn)化成樹的閾值,也就是8,比如數(shù)組里有一個node,這個   
      // node鏈表的長度達(dá)到該值才會轉(zhuǎn)化為紅黑樹。
    static final int TREEIFY_THRESHOLD = 8;
    //當(dāng)一個反樹化的閾值,當(dāng)這個node長度減少到該值就會從樹轉(zhuǎn)化成鏈表
    static final int UNTREEIFY_THRESHOLD = 6;
    //滿足節(jié)點(diǎn)變成樹的另一個條件,就是存放node的數(shù)組長度要達(dá)到64
    static final int MIN_TREEIFY_CAPACITY = 64;
    //具體存放數(shù)據(jù)的數(shù)組
    transient Node<K,V>[] table;
    //entrySet,一個存放k-v緩沖區(qū)
    transient Set<Map.Entry<K,V>> entrySet;
    //size是指hashMap中存放了多少個鍵值對
    transient int size;
    //對map的修改次數(shù)
    transient int modCount;
    //加載因子
    final float loadFactor;


HashMap的構(gòu)造方法


//只有容量,initialCapacity
public HashMap(int initialCapacity) {
    this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
public HashMap() {
    this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}
public HashMap(Map<? extends K, ? extends V> m) {
    this.loadFactor = DEFAULT_LOAD_FACTOR;
    putMapEntries(m, false);
}
final void putMapEntries(Map<? extends K, ? extends V> m, boolean evict) {
    int s = m.size();
    if (s > 0) {
        if (table == null) { // pre-size
            float ft = ((float)s / loadFactor) + 1.0F;
            int t = ((ft < (float)MAXIMUM_CAPACITY) ?
                     (int)ft : MAXIMUM_CAPACITY);
            if (t > threshold)
                threshold = tableSizeFor(t);
        }
        else if (s > threshold)
            resize();
        for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) {
            K key = e.getKey();
            V value = e.getValue();
            putVal(hash(key), key, value, false, evict);
        }
    }
}

public HashMap(int initialCapacity, float loadFactor) {
    if (initialCapacity < 0) // 容量不能為負(fù)數(shù)
        throw new IllegalArgumentException("Illegal initial capacity: " +
                                           initialCapacity);
    //當(dāng)容量大于2^31就取最大值1<<31;                                        
    if (initialCapacity > MAXIMUM_CAPACITY)
        initialCapacity = MAXIMUM_CAPACITY;
    if (loadFactor <= 0 || Float.isNaN(loadFactor))
        throw new IllegalArgumentException("Illegal load factor: " +
                                           loadFactor);
    this.loadFactor = loadFactor;
    //當(dāng)前數(shù)組table的大小,一定是是2的冪次方
    // tableSizeFor保證了數(shù)組一定是是2的冪次方,是大于initialCapacity最結(jié)進(jìn)的值。
    this.threshold = tableSizeFor(initialCapacity);
}


HashMap的哈希沖突解決方法-鏈?zhǔn)降刂贩?/span>

  • 如何HashMap和HashTable存放數(shù)據(jù)的不同(哈希值的來源)?

HashMap的hash值:通過key的來計算得到的hash值,每一個hash值對應(yīng)一個數(shù)組下標(biāo),由于不同的key值可能具有相同的hash值,即一個數(shù)組的某個位置出現(xiàn)兩個相同的元素,對于這種情況,Hashmap采用鏈表的形式進(jìn)行存儲。(使用鏈表進(jìn)行鏈接);

  public V put(K key, V value) {
        return putVal(hash(key), key, value, falsetrue);
    }
--------------------------------------------
 static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

HashTable的hash值:直接通過Key拿到hash值

 public synchronized V put(K key, V value) {
        // Make sure the value is not null
        if (value == null) {
            throw new NullPointerException();
        }
        // Makes sure the key is not already in the hashtable.
        Entry<?,?> tab[] = table;
        int hash = key.hashCode();
        int index = (hash & 0x7FFFFFFF) % tab.length;
        @SuppressWarnings("unchecked")
        Entry<K,V> entry = (Entry<K,V>)tab[index];
        for(; entry != null ; entry = entry.next) {
            if ((entry.hash == hash) && entry.key.equals(key)) {
                V old = entry.value;
                entry.value = value;
                return old;
            }
        }
        addEntry(hash, key, value, index);
        return null;
    }

HashMap采用Entry數(shù)組來存儲key-value對,每一個鍵值對組成了一個Entry實(shí)體,Entry類實(shí)際上是一個單向的鏈表結(jié)構(gòu),它具有Next指針,可以連接下一個Entry實(shí)體。HashMap底層是以數(shù)組方式進(jìn)行存儲的。將key-value鍵值對作為數(shù)組的一個元素進(jìn)行存儲


只是在JDK1.8中,鏈表長度大于8的時候,鏈表會轉(zhuǎn)成紅黑樹。


HashTable(鏈表加數(shù)組)

HashMap和Hashtable都實(shí)現(xiàn)了Map接口,并且都是key-value的數(shù)據(jù)結(jié)構(gòu)。它們的不同點(diǎn)主要在三個方面:

(1)Hashtable是Java1.1的一個類,它基于陳舊的Dictionary類。而HashMap是Java1.2引進(jìn)的Map接口的一個實(shí)現(xiàn)。

(2)Hashtable是線程安全的,也就是說是線程同步的,而HashMap是線程不安全的。也就是說在單線程環(huán)境下應(yīng)該用HashMap,這樣效率更高。

(3)HashMap允許將null值作為key或value,但Hashtable不允許(會拋出NullPointerException)。

(4)哈希值的使用不同:HashTable直接使用對象的hashCode,HashMap重新計算hash值,而且用與代替求模;

(5)HashTable中hash數(shù)組默認(rèn)大小是11,增加的方式是 old*2+1。

HashMap中hash數(shù)組的默認(rèn)大小是16,而且一定是2的指數(shù)。


public class Hashtable<K,V>
    extends Dictionary<K,V>
    implements Map<K,V>, Cloneable, java.io.Serializable {
    /**
    哈希表數(shù)據(jù)
     */
    private transient Entry<?,?>[] table;
    /**
    哈希表中的條目總數(shù)
     */
    private transient int count;
    /**
   當(dāng)表的大小超過此閾值時,表將被重新映射。 
   (此字段的值為(int)(capacity loadFactor)。
     */
    private int threshold;
    /**
    哈希表的加載因子
     */
    private float loadFactor; 
    /**
    此哈希表經(jīng)過結(jié)構(gòu)修改的次數(shù)
     */
    private transient int modCount = 0;
    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    private static final long serialVersionUID = 1421746759512286392L;
    /**
    *使用指定的初始容量和指定的負(fù)載因子構(gòu)造一個新的空哈希表
     */
    public Hashtable(int initialCapacity, float loadFactor) {
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal Load: "+loadFactor);

        if (initialCapacity==0)
            initialCapacity = 1;
        this.loadFactor = loadFactor;
        table = new Entry<?,?>[initialCapacity];
        threshold = (int)Math.min(initialCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
    }

    /**
   使用指定的初始容量和默認(rèn)的加載因子(0.75)構(gòu)造一個新的空哈希表
     */
    public Hashtable(int initialCapacity) {
        this(initialCapacity, 0.75f);
    }
    /**
    構(gòu)造一個新的空哈希表,其默認(rèn)初始容量(11)*和負(fù)載因子(0.75)
     */
    public Hashtable() {
        this(11, 0.75f);
    }

    /**
    *構(gòu)造一個新的哈希表,該哈希表具有與給定 Map相同的映射。
    創(chuàng)建哈希表時,其初始容量應(yīng)足以將給定Map中的映射保存并具有默認(rèn)的加載因子(0.75)
     */
    public Hashtable(Map<? extends K, ? extends V> t) {
        this(Math.max(2*t.size(), 11), 0.75f);
        putAll(t);
    }


為什么HashTable線程安全?

方法使用 synchronized獲取鎖,實(shí)現(xiàn)線程安全

   public synchronized V put(K key, V value) {
        // Make sure the value is not null
        if (value == null) {
            throw new NullPointerException();
        }
        // Makes sure the key is not already in the hashtable.
        Entry<?,?> tab[] = table;
        int hash = key.hashCode();
        int index = (hash & 0x7FFFFFFF) % tab.length;
        @SuppressWarnings("unchecked")
        Entry<K,V> entry = (Entry<K,V>)tab[index];
        for(; entry != null ; entry = entry.next) {
            if ((entry.hash == hash) && entry.key.equals(key)) {
                V old = entry.value;
                entry.value = value;
                return old;
            }
        }
        addEntry(hash, key, value, index);
        return null;
    }


ConcurrentHashMap

哈希表支持檢索的完全并發(fā)和更新的高期望并發(fā)。此類遵循與{@link java.util.Hashtable}相同的功能規(guī)范,并且包含與{{code Hashtable}的每個方法相對應(yīng)的方法的版本。但是,即使所有操作都是線程安全的,但檢索操作 并不需要進(jìn)行鎖定,并且 對以鎖定方式鎖定整個表沒有任何支持阻止所有訪問。在依賴于其線程安全但不依賴于其同步詳細(xì)信息的程序中,此類可以與{@code Hashtable}完全互操作

 static class Segment<K,V> extends ReentrantLock implements Serializable {
        private static final long serialVersionUID = 2249069246763182397L;
        final float loadFactor;
        Segment(float lf) { this.loadFactor = lf; }
    }

ConcurrentHashMap 中有一個 Segment 的概念。Segment 本身就相當(dāng)于一個 HashMap 對象。同 HashMap 一樣,Segment 包含一個 HashEntry 數(shù)組,數(shù)組中的每一個 HashEntry 既是一個鍵值對,也是一個鏈表的頭節(jié)點(diǎn);


ConcurrentHashMap 集合中有 2 的N次方個 Segment 對象,共同保存在一個名為 segments 的數(shù)組當(dāng)中;




  • 采取了鎖分段技術(shù),每一個 Segment 就好比一個自治區(qū),讀寫操作高度自治,Segment 之間互不影響;

但是操作同一個 Segment需要加鎖的,但檢索操作 并不需要進(jìn)行鎖定,并且

對以鎖定方式鎖定整個表沒有任何支持阻止所有訪問。在依賴于其線程安全但不依賴于其同步詳細(xì)信息的程序中,此類可以與Hashtable完全互操作


總結(jié):ConcurrentHashMap是線程安全的,并且鎖分離。ConcurrentHashMap內(nèi)部使用段(Segment)來表示這些不同的部分,每個段其實(shí)就是一個小的hash table,它們有自己的鎖。只要多個修改操作發(fā)生在不同的段上,它們就可以并發(fā)進(jìn)行

————————————————

版權(quán)聲明:本文為CSDN博主「代碼與她皆過客」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。

原文鏈接:

https://blog.csdn.net/weixin_44313584/article/details/115051897




鋒哥最新SpringCloud分布式電商秒殺課程發(fā)布

??????

??長按上方微信二維碼 2 秒





感謝點(diǎn)贊支持下哈 

瀏覽 38
點(diǎn)贊
評論
收藏
分享

手機(jī)掃一掃分享

分享
舉報
評論
圖片
表情
推薦
點(diǎn)贊
評論
收藏
分享

手機(jī)掃一掃分享

分享
舉報

感谢您访问我们的网站,您可能还对以下资源感兴趣:

国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频 亚洲黄色AV| 精品99999| 丰满人妻一区二区三区不卡二| 亚洲高清无码免费观看| 成人无码日韩| 日韩精品成人专区无码| 亚洲无码。| 亚洲无码成人视频| 怡春院中文字幕| 色五月激情小说| 色图欧美色图| av三级片在线播放| 日本中文视频| 婷婷久久久| 青草视屏| 超碰天天爱| 懂色成人av影院| 久草视频在线免费看| 一卡二卡无码| 国产乱伦熟女| 黄片视频国产| 成人免费无码激情AV片| 久久精品视频网站| 夜夜嗨老熟女AV一区二区三区| 日韩av在线看| 久激情内射婷内射蜜桃欧美一级 | 无码人妻精品一区二区蜜桃漫画| 不卡二区| 成人H视频| 久久停停| 黄色成人毛片| 中文字幕一区二区二三区四区 | 日韩免费看| 青青草东路热vv| 一个人看的www日本高清视频| 成人无码区免费AV片| 亚洲欧美另类图片| 国产成人a亚洲精品无码| 在线日韩中文字幕| 大香蕉东京热| 丁香花在线小说免费全文| 成人性爱视频网| 囯产精品宾馆在线精品酒店| 91福利影院| 在线观看视频黄| 黄色一级在线| 亚洲五月天在线| 边摸边做| 亚洲成人少妇老妇a视频在线| 激情五月激情综合网| 婷婷五月亚洲| 日韩色情网| 午夜国产码网站码| 屁屁影院CCYYCOM国产| 亚洲精品一区二三区不卡| 日韩AⅤ无码一区二区三区| 欧洲一区二区三区| 国产亚洲欧美日韩高清| 色五月婷婷综合| 午夜爽爽视频| 日本丰满老熟妇乱子伦| 男人的天堂色琪琪| 怡红院男人天堂| 奇米av在线| 91九色在线观看| 中文字幕第27页| 91精品人妻一区二区三区蜜桃欧美 | 97欧美日韩| 一区二区三区高清无码| 黑人毛片91久久久久久| 午夜激情av| 五月乱伦| 9I看片成人免费视频| 中文字幕中文字幕无码| 国产精品久久久久永久免费看| 亚洲日韩精品无码| 国产精品黄色| 豆花天天吃最新视频| 中国1级毛片| 强开小嫩苞一区二区电影| 成人影片在线观看18| 人人看人人做| 激情网站在线| 91sese| 粉嫩护士小泬18p| 亚洲人视频| 中文三级片| 黄色国产在线| 在线观看亚洲视频| 欧美人妻日韩精品| 欧美精产国品一| 91无码精品国产| 大地中文资源5页的更新内容| 91无码人妻传媒tv| 伊人大香蕉综合在线| 98无码人妻精品一区二区三区 | 坏男人内射老太太| 午夜老司机福利| 五月丁香婷婷色| 日韩超清无码| 少妇无码| 无码人妻精品一区二区蜜桃91| 嘿嘿午夜影院| 亚洲黄色视频网站| 家庭乱伦av| 国产一区2区| 手机看片久久| 99看片| 亚州一级二级| 亚洲视频一区二区| 黄色片在线观看视频| 日韩精品毛片一区二区视频免费 | 娇小,学生,高潮,videos| 韩国无码一区| 大地资源第5页在线| 中文字幕在线免费| 欧美日韩东京热| 先锋影音资源一区| 东方美美高清无码一区| 色天天| 国产精品一色哟哟哟| 米奇7777狠狠狠狠| 超碰在线观看91| 欧美成人看片黄a免费看| 青娱乐亚洲精品视频| 青青草无码成人天堂免费| 先锋资源一区| 男人的天堂色琪琪| 久久久久久久| 无码乱伦视频| 国产操逼大片| 国产精品欧美性爱| 九九99久久| 中文有码在线| 午夜视频免费| 成人国产片| 亚洲女人天堂| 一区二区三区高清| 天天摸天天干| 91探花秘入囗| 青青操首页| 久草这里只有精品| 亚洲欧美日韩色图| 精品一区二区免费| 欧美精品xxx| 国产成人精品在线观看| 国产一级女婬乱免费看| 99热热| 国产91麻豆视频| 中文一区二区| 久久久久久AV| 老婆中文字幕乱码中文乱码| 成人黄A片免费| 欧美黄片在线免费看| 日韩无码毛片| 波多野结衣在线无码| 99久久婷婷| 亚洲国产成人视频| 天天综合字幕一区二区| 日韩视频在线免费观看| 最近中文字幕| 午夜无码高清| 91麻豆精品在线观看| 影音先锋女人aV鲁色资源网站| 日韩精品在线观看视频| 人人操av| 依人大香蕉| 97国产资源| 在线无码视频观看| 黄色视频在线观看免费| 囯产精品久久久久久久久久| 九九久久综合| 国产香蕉在线视频| 欧美自拍第一页| 婷婷五月免费视频| 天堂在线社区| 国产午夜福利视频| 特级西西人体WWWww| 高潮无码视频| 日韩欧美精品一区二区| 草草影院第一页| 可以免费看的黄色视频| 操鸡视频在线观看| 亚洲一区无码在线观看| 免费一级黄色毛片| 六月丁香五月天| 丁香婷婷色五月| 国产电影一区二区三区| 91免费视频观看| 五月丁香成人| 黄色小视频在线免费看| 中文字幕手机在线视频| 亚洲国产成人在线视频| 伊人黄色片| 一本久道无码| 蝌蚪窝在线视频观看| 一级a一级a爰片免费免免在线| 国产久久免费视频| 亚洲成人网站在线| 另类老妇奶BBBBwBB| 豆花AV在线| 新版欧美内射大全| AV黄色在线| 国产人妖网站| 在桌下含她的花蒂和舌头H视频| 高清无码直接看| 一区二区三区高清不卡| 国产91www| 嫩BBB搡BBBB搡BBBB| 中文在线最新版天堂8| 日韩人妻精品中文字幕| 水果派AV解说| 精品免费国产一区二区三区四区的使用方法| 亚洲性爱视频在线观看| 在线超碰| 欧美激情五月天| 日韩无码一二三| 老司机免费视频| 亚洲精品国产精品国自产在线| 91九色91蝌蚪91成人| 国产不卡在线观看| 亚洲色偷精品一区二区三区| 波多野结衣久久中文字幕| 99久久婷婷国产综合精品hsex| 久激情内射婷内射蜜桃欧美一级 | 日韩一区二区无码视频| 国产一区二区不卡亚洲涩情| 国产精品色在线| 高清无码操逼视频| 韩国三级中文字幕HD久久精品| 精品人妻一区二区三区四区| 亚洲高清无码免费在线观看| 操逼视频国产91| 欧美色图狠狠操| 乱伦乱伦乱伦中文字幕| 精品无人区无码乱码毛片国产| 日本中文字幕精品| 九月丁香婷婷| 欧美色图另类图片| 67194国产| 久久久久久精| 青青草综合网| 国产福利视频在线观看| 日韩二级片| 亚洲免费观看高清完| 嫩BX区二区三区的区别| 一区二区无码av| 强开小嫩苞一区二区电影| 天天日夜夜| 先锋av资源在线| 亚洲.欧美.丝袜.中文.综合| 久久国产无码| 欧一美一婬一伦一区二区三区自慰国 | 无码777| 秋霞福利| 人人操人人人| 久久伊人精品| 中出欧美亚洲| 色婷婷国产精品视频| 成人亚洲AV日韩AV无码| 手机看片福利永久| 精品视频999| 久草视频福利| 性欧美V| 肏屄视频在线播放| 欧美色婷婷| 九九美女视频| 91麻豆香蕉| 高清无码一区| 免费黄色av网址| 成人无码三级| 做爱的网站| 91精品成人电影| 免费成人毛片| 射射AV| 91视频网站在线| 伊人在线视频| 成人性爱视频免费观看| 做爱无码| 四虎在线视频观看96| 暖暖高清无码| 黑人无码视频| 国产美女被爽到高潮免费A片软件| 男人天堂手机在线| 国产96在线亚洲| 翔田千里无码AV在线观看| 成人免费黄色| 黄色a片网站| 中国黄色学生妹一级片| 97综合| 欧美色影院| A毛片| 国产AV日韩AⅤ亚洲AV中文| 成人久久av| 69AV在线| 日韩三级精品| 日韩草逼| 黄色成人网站大全| 羞羞视频com.入口| 欧美日韩逼| 97国产资源| 欧美精产国品一二三| 狠狠操免费| 超碰人人草| 色久悠悠综合网| 久久综合五月天| 精品人妻一二三区| 日韩性生活网| 超碰大香蕉| 日日夜夜无码| 成人精品午夜无码免费| 天天干夜夜操| 日本综合在线| 亚洲国产成人精品激情在线| jizzjizz欧美| 亚洲中文字幕人妻。| 国产熟女露脸普通话对白| 国产精品免费在线| 91亚洲国产成人久久精品网站| 成人毛片18女人毛片| 97爱视频| 人人草在线视频| 中文字幕无码乱伦| 毛片在线观看视频| 国产在线成人视频| 亚洲国产精品午夜福利| 成人免费毛片视频| 色噜噜狠狠一区二区三区牛牛影视| 国产亚洲av| 日本爱爱免费播放视频| 黄色免费网站在线观看| 日韩一区二区三区免费视频| 不卡二区| 2019天天操| 亚洲v在线| 黄色国产视频在线观看| 日皮视频免费观看| 成人性爱视频在线| 操欧美逼| 日本中文字幕在线免费观看| 东京热AV在线| 日韩国产三级| 亚洲的天堂的αⅴ| 天天干天天日天天干天天日| 成人免费无码婬片在线观看免费| 亚洲婷婷视频| 91av| 韩国gogogo高清在线完整版| 亚洲无码一| 在线播放91灌醉迷J高跟美女| 99色| 少妇搡BBBB搡BBB搡小说| 成人A片免费| 五月丁香激情在线| 久久av一区二区三区| 人人摸在线视频| 伊人大香蕉在线观看| 国产亲子乱婬一级A片借种| 亚洲AV成人无码精在线| 亚洲ww国产a大作| 久久成人精品| 五月婷视频| 三级视频在线观看| 欧美大香蕉伊人| 97在线鲁碰免费视频| 婷婷五月天色色| 激情av在线观看| 你懂得在线观看| 蜜芽av在线观看| 午夜欧美| 7777精品伊人久久7777| 韩国精品一区二区| 亲孑伦XXXⅹ熟女| 成人A片一级| 精品国产区一区二| 国产一区二区三区视频| 成人做爰黄A片免费视频网站野外| 色mm在线播放| 91在线综合| 一級免費网站| 加勒比无码| 999精品| 久久麻豆| 亚洲AV成人无码一区二区三区| 日韩精品在线观看视频| 一本色综合亚洲精品| 北条麻妃无码在线视频| 欧洲成人免费视频| 黄色小说在线看| 99re视频在线| 乱伦视频91| 2025精品精品视频| 91无码人妻一区二区成人AⅤ| 亚洲一卡二卡| 久久免费视频网站| 黑人无码视频| 欧美区亚洲区| 白虎高清无码大尺度免费在线观看| 蜜桃视频在线观看视频| 欧美一区二区三区激情| 国产无套免费网站69| 高清毛片AAAAAAAAA片| 日韩av毛片| 国产福利在线导航| 日韩高清不卡| 国产视频h| 伊人大香蕉视频| 日本中文字幕免费| 日韩无码视频二区| 五月婷久久| 国产乱子伦一区二区三区视频| 99久久婷婷国产综合精品hsex,亚| youjizzcom日本| 日本高清不卡视频| 欧美性生活视频| 午夜成人精品视频| 一级特黄妇女高潮AA片免费播放| 日韩乱轮小说与视频| 香蕉操逼视频| 精品丰满人妻一区二区三区免费观| 久久久久亚洲| 日韩怡春院| 国产超级无码高清在线视频观看| 天天综合色| 高清无码免费看| 亚洲成人福利电影| 综合激情AV| 日本成人视频在线免费播放| 成人短视频在线观看| 噜噜| 日韩视频一区二区| 成年视频网站| 色综合五月| 成人国产精品视频| 91精品丝袜久久久久久| 日本少妇视频| 欧美性爱xxxx| 中国老少配BBwBBwBBW| 米奇色色| 国产成人免费在线视频| 足交 | 国产自偷自拍| 老婆被黑人杂交呻吟视频| 国产操P| 18禁一区二区三区| 五月停亭六月,六月停亭的英语| 天堂成人在线视频| 日本a片在线观看| 猛男大粗猛爽h男人味| 天天干天天干天天| 91精品电影| 亚洲成人无码高清| 中文字幕日韩人妻| 国产黄色片视频| 国产精品欧美激情| 欧美色图第一页| 免费无码又爽又黄又刺激网站| 亚洲AV综合色区无码国产播放| 大香焦久久| 成熟的国模冰莲[2]| 亚洲国产精品成人va在线观看| 免费a视频在线观看| 久草视频在线免费看| 大香蕉一级红色片青青河边草| 亚洲VA| 97久久综合| 91欧美视频| 国产亚洲99久久精品熟女| 六月婷婷深爱| 臭小子啊轻点灬太粗太长了的视频| 97人妻人人澡人| 日本AⅤ中文字幕| 亚洲不卡在线观看| 狠狠躁夜夜躁人人爽视频| 国产精品777| 日韩人妻码一区二区三区| 日本欧美成人片AAAA| 亚洲免费无码视频| 久久久WWW成人免费精品| 国产精品在线免费| 免费操逼| 国产激情福利| 欧美亚洲国产视频| 在线观看国产欧美| 中国熟妇XXXX18| 麻豆一区在线观看| 91二区| 狠狠干综合| 欧美不卡一区二区三区| BBw日本熟妇BBwHD| 444444免费高清在线观看电视剧的注意| 蜜桃久久久| 丝袜一区二区三区| 国产噜噜噜噜噜久久久久久久久| 北条麻妃在线无码| 久一精品| 操逼视频一级| 337P大胆粉嫩噜噜噜| 日韩视频在线观看免费| 天天添| 男女啪啪啪网站| 五月天婷婷操逼视频| 亚洲第一色网| 蜜桃操逼| 亚洲无吗视频| 国产黄h| 久久综合五月| 亚洲性爱在线播放| 午夜亚洲AⅤ无码高潮片苍井空| 驲韩在线视频免费观看| 亚洲欧洲日韩综合| 99热在线观看精品| 欧美黄片免费看| 操屄免费视频| 精品久久一区二区| 波多野结衣视频免费在线观看 | 香蕉漫画在线观看18| 在线免费观看黄| 国产毛片毛片毛片毛片毛片| 97精品超碰一区二区三区| 老鸭窝av免费入口在线观看| 肏屄在线视频| 黄色大片免费在线观看| 亚洲国产视频一区| 亚洲激情视频网站| 久热超碰| 欧美日韩高清无码| 黄色三级电影| 亚洲天堂在线免费观看视频| 美女黄色视频永费在线观看网站 | 操屄免费视频| 一级黄色操逼视频| 亚洲国产视频一区| 日韩无码二级| 免费一区二区三区四区| 中文字幕人妻丰满熟妇| 麻豆一区在线观看| 91嫖妓站街按店老熟女| 亚洲精品三级在线观看| 亚洲色图欧美| 日韩啪啪视频| AV一区二区在线观看| 中文字幕日本| 少妇熟女视频一区二区三区| 欧美777| H片在线免费观看| 日韩婬乱片A片AAA真人视频| 丰满熟妇人妻无码视频| 无码人妻精品一区二区三区温州| 黄色A片约| 国产激情无码视频| 国产超碰青青草| 国内自拍2025| 人人摸人人摸| 天天激情| 欧美日韩中文字幕| 日韩大屌| 在线播放日韩| 熟妇无码| 在线观看禁无码精品| 九九激情| 婷婷国产精品视频| 99国产高清| 青青啪啪啪| 日本少妇视频| 久久草在线观看| 一区二区三区黄色| 先锋资源av在线| 成人做爰黄片视频免费| 影音先锋麻豆传媒| 久操免费在线| 国产精品国产伦子伦露看| 自拍偷拍15p| 探花一区二区| 精品吃奶一区二区三区视频| 操逼不卡视频| 国产你懂的| 亚洲无码系列| 精品乱子伦一区二区三区免费播放| 肏逼网址| 亚洲精品一区二区三区无码电影| 激情综合网五月婷婷| 亚洲国产精品欧美久久| 免费中文资源在线观看| 黄视频免费在线观看| 亚洲AV无码一区| 日本欧美黄色| 波多野结衣无码AV| 一区二区无码av| 毛片A| 久久色在线视频| 国产精品一区网站| 天天操天天操| 自拍超碰| 97久久久| 18毛片| 911精品人妻一区二区三区A片| 安徽妇搡BBBB搡BBBB按摩| 五月天婷婷综合网| 精品国产久久久久| 成人精品在线视频| 亚洲免费观看高清完整版在va线观 | 久久精品毛片| 亚洲内射网| 婷婷丁香五月激情一区综合网| 丁香六月婷婷综合| 一区二区无码在线| 国产调教视频| 婷婷九九| 亚洲国产黄色视频| 国产一片黑夜内射| 自拍视频国产| 日本一级特黄大片AAAAA级| 日韩精品无码人妻| 国产看色免费| 久久久www成人免费毛片| 午夜黄色操逼视频| 撸一撸成人在线做爱视频。| 一级AA片| 操操操操操| 黄色A片网站| 成人伊人大香蕉| 日韩精品一二三| 亚洲成人AV在线播放| 国产精品国产三级国产AⅤ原创| 国产日韩一区二区三区| 日韩在线观看中文字幕| 69成人在线| 黄色国产视频在线观看| 成年人免费公开视频| 在线看一区二区三区| 免费无码婬片A片AA片| 欧美日韩不卡在线| 亚洲成人性爱av| 亚洲品久久久蜜| 色男人天堂| 欧美日本国产| 欧美激情一区| 操逼在线视频| 日本黄色电影网址| 亚洲成人视频网站| 最新超碰| 国产操逼逼| 成人欧美大片黄18| 高清无码在线观看18| 农村乱子伦毛片国产乱| 亚洲成人福利| 中文字幕第2页| 日韩免费在线播放| 国产色拍| 黄色视频免费观看国产| av三级网站| 69福利| 伊人大香蕉精品| 青青草原在线视频免费观看| 天天爆操| 日本乱码视频| 特级毛片在线观看| 国产換妻4P视频| 青娱乐偷窥成| 亚洲国产操逼| 香蕉av在线播放| 天天色网站| 熟女一区二区三区| 亚日韩视频| 久久特黄| 高潮视频在线| 欧美性爱免费在线视频| 国产精品一级A片| 久亚洲| 日韩欧美偷拍| 久久av网站| 人人爽人人操人人爱| 免费国产精品视频| 蜜桃久久久亚洲| 午夜美女福利视频| 天天天日天天天天天天天日歌词| 日本老女人视频| 亚洲无码视频在线免费观看| 天天舔天天干| 免费成人视频| 亚洲福利视频网站| 东方a在线| 高潮国产视频| 91丨九色丨蝌蚪丨成人| 中文二区| 91亚洲在线| 青青草免费公开视频| 99热99| 插逼综合网| 欧美成人毛片AAAAAA| 亚洲激情| 翔田千里高潮90分钟| 日韩中文字幕一区二区三区| 黄片视频链接| 大香蕉伊人网视频| 超碰97成人| 天堂va欧美ⅴa亚洲va一夜 | 国产又爽又黄免费视频免费观看| 日韩人妻无码专区一区二区| 免费三区| 欧洲成人无码| 三级片网页| 国产美女在线观看| 91在线成人电影| 黄色成人视频网站| 欧美国产日韩视频| 69成人| 九九黄色| 俺去俺来WWW色官方| 天天综合网久久综合网| www.色五月| 亚洲视频第一页| 偷拍欧美日韩| 国产精品爽爽久久久久| 97久久久| 欧美精品久久久| 成人片成人网久久蜜桃臀| 岛国A视频| 麻豆传媒一区| 亚洲爱爱网站| 囯产一级a一级a免费视频| 欧美老女人性爱视频| 豆花视频成人版www满18| 中文字幕在线观看网址最新地址| 操BBBB| 亚洲综合小说| 东京热在线观看| 国产成人精品无码片区在线观91 | A级无码| AV无码在线观看| 国产剧情一区二区av在线观看 | 激情综合在线| 精品久久一区二区三区四区| 手机在线观看AV| 国产精品久久久久久久久久九秃 | 欧美午夜片| 亚洲一区无码在线观看| 日本一级特级毛片视频| 91黄色视频在线播放| 中文字幕在线免费看线人| 国产一区二区三区视频在线观看| sesese999| 18禁免费网站| 免费看毛片中文字幕| 日日夜夜超碰| 日韩美在线| 久草资源在线观看| 97福利在线| 青青草综合网| 日韩a| 久久免费看视频| 国产有码在线观看| 欧美后门菊门交3p、| 黄色免费看视频| 国精产品一区一区三区四川| 操逼网站免费| 成人抽插视频| 天天搞搞| 伊人黄色视频| 久热草| 国产欧美一区二区三区四区| 日韩欧美一级视频| 91乱子伦国产乱子伦海的味道| 日日碰狠狠| 免费看A级片| 日韩欧美在线免费| 十八禁无码| 草草在线视频| 国产无码专区| 欧美日韩AV| 亚洲日韩中文字幕| 成人三级片视频| 少妇搡BBBB搡BBB搡毛片少妇| av资源在线看| 加勒比无码| 99欧美| 亚洲AV无码日韩AV无码导航| 亚洲精品福利视频导航| 欧美三级一级| 欧美黄色免费观看| 麻豆国产91在线播放| 九九久久国产精品| 另类老妇奶性生BBwBBw偷拍| 大香蕉这里只有精品| 亚洲午夜久久久久久久久红桃| 精品一区在线| 北条麻妃久久网站| 日韩欧美大香蕉| 一级特黄妇女高潮AA片免费播放 | 国产美女被爽到高潮免费A片软件| 成人福利视频在线观看| 亚洲黄色小视频| 亚洲精品秘一区二区三线观看| 久久黄色网络| 五十路熟妇| 国产无码小视频| 26∪u∪成人网站| 成人喷水亚洲一区无码| 精品中文一区二区三区| 性色A| 老妇槡BBBB槡BBBB槡| 91亚洲视频在线观看| gogogo视频在线观看黑人| 亚洲国产成人精品女人久久| 伊人免费在线| 久久男人天堂| 91丝袜一区二区| 开心五月色婷婷综合开心网| 暖暖高清无码| 国产成人AV在线播放| 婷婷五月天丁香| 无码天天| 五月天久久久久| 在线播放JUY-925被丈夫上司侵犯的第7天 | 精品久久久久久久久久| 日韩三级片av| 人人弄| 神马午夜秋霞不卡| 成人性生活免费视频| 西西4444www无码精品| 中文字幕激情精品| 性爱福利导航| 久久免费在线视频| 91伊人网| 三级久久网| 国产三级视频在线| 欧美日韩操逼视频| 蜜桃精品一区二区三区美女| 你懂得视频在线观看| 日韩成人视频在线| 四虎麻豆| 91探花视频精选在线播放| 国产人国产视频成人免费观看… | 成人午夜小视频| 大香蕉伊人综合| 国产三级AV在线观看| 欧美h在线观看| 最近中文字幕mv第三季歌词| 中文一区二区| 国产乱色精品成人免费视频| 亚洲女人视频| 在线视频你懂得| 色久悠悠综合网| 粉嫩小泬BBBBBB免费看| 久久国产精品久久| 少妇人妻偷人精品无码视频新浪| 影音先锋蜜桃| A片在线观看免费| 乱伦天堂| 91视频电影| 亚洲精品中文字幕乱码三区91| 激情视频网| 五月婷婷狠狠爱| www高清无码| 欧美熟妇精品一级A片视色| 成人肏逼视频在线| 免费无码婬片AAAA片在线蜜芽| 一道本无码在线| 女女久久| 视色网站| 91久色| 欧美天天性| 亚洲综合中文字幕在线| 欧美成人无码A片免费| 人人操干| 欧美日韩在线视频免费| 大香蕉伊人影院| 亚洲三区视频| 亚洲AV成人无码一区二区三区| 欧美性爱91| 色色com| 一本色道久久无码人妻精品69| 激情综合婷婷| 久久久久久麻豆| 撸一撸在线观看| 色色视频网站| 国产精品毛片一区视频播| 亚洲一区二区三区在线播放| 人人人人人操| 久久久久久成人无码| 日本内射在线播放| 91在线无码精品秘入口动作 | 国产中文字幕AV在线播放| 欧美aaa在线| 婷婷色亚洲| 综合成人在线| 日韩图色| 国产精成人品| 农村A片婬片AAA毛片| 91精品国产综合久久久蜜臀图片| 久久精品苍井空免费一区二| 亚洲精品一区二区三区在线观看| 99久久久精品久久久久久| 男人天堂色男人| 91无码国产| 性爱AV在线| 神马午夜福利视频| 蜜臀av网站| 国产亚洲激情|