精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

HashMap鏈表樹化閾值深度解析:為什么是8而不是7或9?

開發 前端
在JDK 8之前,HashMap完全基于數組+鏈表實現。當發生哈希沖突時,新元素會被添加到鏈表末尾。隨著元素增多,鏈表可能變得很長,導致查詢效率從O(1)退化為O(n)。

在Java集合框架中,HashMap作為最常用的數據結構之一,其性能優化一直是開發者關注的焦點。JDK 8引入了一項重要優化:當哈希桶中的鏈表長度超過一定閾值時,會將鏈表轉換為紅黑樹。這個閾值被設定為8,這一數字背后蘊含著深刻的設計思想和數學原理。本文將深入剖析這一設計決策的技術細節,通過源碼分析、數學證明和性能測試,全面解析為什么選擇8作為樹化閾值。

一、HashMap基礎結構與樹化背景

1.1 HashMap底層實現演進

在JDK 8之前,HashMap完全基于數組+鏈表實現。當發生哈希沖突時,新元素會被添加到鏈表末尾。隨著元素增多,鏈表可能變得很長,導致查詢效率從O(1)退化為O(n)。

// JDK 7中的HashMap.Entry實現
static class Entry<K,V> implements Map.Entry<K,V> {
    final K key;
    V value;
    Entry<K,V> next;
    int hash;
    
    Entry(int h, K k, V v, Entry<K,V> n) {
        value = v;
        next = n;
        key = k;
        hash = h;
    }
}

JDK 8引入了紅黑樹優化,當鏈表長度達到閾值時轉換為樹結構:

// JDK 8中的Node和TreeNode
static class Node<K,V> implements Map.Entry<K,V> {
    final int hash;
    final K key;
    V value;
    Node<K,V> next;
    
    // 構造函數...
}

static final class TreeNode<K,V> extends LinkedHashMap.Entry<K,V> {
    TreeNode<K,V> parent;  // 紅黑樹鏈接
    TreeNode<K,V> left;
    TreeNode<K,V> right;
    TreeNode<K,V> prev;    // 刪除后需要取消鏈接
    boolean red;
    
    // 樹操作方法...
}

1.2 樹化的觸發條件

HashMap中樹化的條件并非單一因素決定,而是綜合考慮鏈表長度和哈希桶數組大小:

public class HashMap<K,V> extends AbstractMap<K,V> 
    implements Map<K,V>, Cloneable, Serializable {
    
    // 樹化閾值 - 當鏈表長度達到此值時轉換為紅黑樹
    static final int TREEIFY_THRESHOLD = 8;
    
    // 取消樹化閾值 - 當樹節點數小于此值時轉換回鏈表
    static final int UNTREEIFY_THRESHOLD = 6;
    
    // 最小樹化容量 - 哈希表容量至少達到此值才會樹化
    static final int MIN_TREEIFY_CAPACITY = 64;
    
    final void treeifyBin(Node<K,V>[] tab, int hash) {
        int n, index; Node<K,V> e;
        // 檢查哈希表容量是否達到最小樹化要求
        if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY)
            resize(); // 先擴容而不是立即樹化
        else if ((e = tab[index = (n - 1) & hash]) != null) {
            // 執行樹化操作
            TreeNode<K,V> hd = null, tl = null;
            do {
                TreeNode<K,V> p = replacementTreeNode(e, null);
                if (tl == null)
                    hd = p;
                else {
                    p.prev = tl;
                    tl.next = p;
                }
                tl = p;
            } while ((e = e.next) != null);
            if ((tab[index] = hd) != null)
                hd.treeify(tab); // 將鏈表轉換為紅黑樹
        }
    }
}

二、樹化閾值的數學基礎:泊松分布

2.1 哈希沖突的概率模型

HashMap設計者使用泊松分布來模擬哈希沖突的概率。在理想的哈希函數下,元素在哈希桶中的分布應該接近均勻分布,但實際上由于哈希函數的局限性,沖突不可避免。

泊松分布的概率質量函數為:

其中λ是每個桶中元素的期望數量,在HashMap中約為0.5(負載因子0.75時)。

2.2 概率計算與閾值選擇

HashMap源碼中的注釋詳細解釋了基于泊松分布的概率計算:

/**
 * 由于樹節點的大小大約是普通節點的兩倍,因此我們僅在桶包含足夠多的節點時才使用樹節點(參見TREEIFY_THRESHOLD)。
 * 當桶中的節點數變得太小時,它們會被轉換回普通的桶。
 * 在具有良好分布的用戶哈希碼的情況下,很少使用樹桶。
 * 
 * 理想情況下,在隨機哈希碼下,桶中節點的頻率遵循泊松分布,其中參數的平均值約為0.5,默認大小閾值為0.75。
 * 忽略方差,列表大小k的預期出現次數為(exp(-0.5) * pow(0.5, k) / factorial(k))。
 * 
 * 0:    0.60653066
 * 1:    0.30326533
 * 2:    0.07581633
 * 3:    0.01263606
 * 4:    0.00157952
 * 5:    0.00015795
 * 6:    0.00001316
 * 7:    0.00000094
 * 8:    0.00000006
 * 更多: 小于千萬分之一
 */

讓我們通過代碼驗證這些概率值:

public class PoissonDistributionAnalysis {
    
    /**
     * 計算泊松分布概率
     * @param lambda 期望值(HashMap中約為0.5)
     * @param k 事件發生次數
     * @return 概率值
     */
    public static double poissonProbability(double lambda, int k) {
        return Math.exp(-lambda) * Math.pow(lambda, k) / factorial(k);
    }
    
    /**
     * 計算階乘
     */
    public static long factorial(int n) {
        if (n <= 1) return 1;
        long result = 1;
        for (int i = 2; i <= n; i++) {
            result *= i;
        }
        return result;
    }
    
    public static void main(String[] args) {
        double lambda = 0.5; // HashMap中的期望值
        
        System.out.println("鏈表長度\t出現概率");
        System.out.println("----------------------");
        
        for (int k = 0; k <= 10; k++) {
            double probability = poissonProbability(lambda, k);
            System.out.printf("%d\t%.8f", k, probability);
            
            // 添加特殊標記
            if (k == 7) System.out.print(" ← 接近樹化閾值");
            if (k == 8) System.out.print(" ← 樹化閾值");
            if (k == 9) System.out.print(" ← 超過閾值");
            
            System.out.println();
        }
        
        // 計算長度>=8的概率
        double cumulativeProbability = 0.0;
        for (int k = 8; k <= 20; k++) {
            cumulativeProbability += poissonProbability(lambda, k);
        }
        System.out.printf("\n鏈表長度≥8的總概率: %.10f", cumulativeProbability);
        System.out.println(" (約千萬分之六)");
    }
}

運行結果:

鏈表長度    出現概率
----------------------
0    0.60653066
1    0.30326533
2    0.07581633
3    0.01263606
4    0.00157952
5    0.00015795
6    0.00001316
7    0.00000094 ← 接近樹化閾值
8    0.00000006 ← 樹化閾值
9    0.00000000 ← 超過閾值
10    0.00000000

鏈表長度≥8的總概率: 0.0000000618 (約千萬分之六)

2.3 閾值選擇的數學意義

從數學角度看,選擇8作為閾值基于以下考慮:

1. 概率極低:鏈表長度達到8的概率約為0.00000006,即千萬分之六

2. 平衡點:在7和9之間,8提供了最佳的性能平衡

3. 實用性:在實際應用中,如此低的概率意味著在正常情況下幾乎不會發生樹化

三、性能分析與權衡

3.1 鏈表與紅黑樹的性能對比

紅黑樹雖然能提供O(log n)的查詢性能,但節點內存開銷和操作復雜度都高于鏈表:

// 性能測試對比
public class PerformanceBenchmark {
    
    private static final int ITERATIONS = 100000;
    
    public static void main(String[] args) {
        // 鏈表性能測試
        long linkedListTime = testLinkedList();
        System.out.println("鏈表平均查詢時間: " + linkedListTime + " ns");
        
        // 紅黑樹性能測試  
        long treeTime = testRedBlackTree();
        System.out.println("紅黑樹平均查詢時間: " + treeTime + " ns");
        
        // 內存占用對比
        compareMemoryUsage();
    }
    
    private static long testLinkedList() {
        LinkedList<Integer> list = new LinkedList<>();
        for (int i = 0; i < 8; i++) {
            list.add(i);
        }
        
        long startTime = System.nanoTime();
        for (int i = 0; i < ITERATIONS; i++) {
            list.contains(7); // 查找最后一個元素,最壞情況
        }
        return (System.nanoTime() - startTime) / ITERATIONS;
    }
    
    private static long testRedBlackTree() {
        TreeSet<Integer> tree = new TreeSet<>();
        for (int i = 0; i < 8; i++) {
            tree.add(i);
        }
        
        long startTime = System.nanoTime();
        for (int i = 0; i < ITERATIONS; i++) {
            tree.contains(7);
        }
        return (System.nanoTime() - startTime) / ITERATIONS;
    }
    
    private static void compareMemoryUsage() {
        // 估算內存占用
        int linkedListMemory = 8 * (16 + 8 + 8); // 8個節點,每個節點約32字節
        int treeMemory = 8 * (16 + 8 + 8 + 8 + 8 + 1); // 樹節點額外開銷
        
        System.out.println("鏈表內存估算: " + linkedListMemory + " bytes");
        System.out.println("紅黑樹內存估算: " + treeMemory + " bytes");
        System.out.println("樹節點內存開銷增加: " + 
            ((double)(treeMemory - linkedListMemory) / linkedListMemory * 100) + "%");
    }
}

3.2 閾值8的性能優勢

選擇8作為閾值在性能上具有明顯優勢:

1. 避免過早樹化:如果閾值設為7,會頻繁觸發樹化,增加不必要的內存和計算開銷

2. 防止鏈表過長:如果閾值設為9,在極端情況下鏈表可能過長影響性能

3. 最佳轉折點:在長度為8時,紅黑樹的O(log n)性能開始明顯優于鏈表的O(n)

四、源碼級別的深入分析

4.1 樹化過程的詳細實現

讓我們深入分析HashMap中樹化的完整過程:

final void treeify(Node<K,V>[] tab) {
    TreeNode<K,V> root = null;
    // 遍歷鏈表,將每個節點轉換為樹節點
    for (TreeNode<K,V> x = this, next; x != null; x = next) {
        next = (TreeNode<K,V>)x.next;
        x.left = x.right = null;
        
        // 建立紅黑樹
        if (root == null) {
            x.parent = null;
            x.red = false; // 根節點為黑色
            root = x;
        } else {
            K k = x.key;
            int h = x.hash;
            Class<?> kc = null;
            
            // 在樹中尋找插入位置
            for (TreeNode<K,V> p = root;;) {
                int dir, ph;
                K pk = p.key;
                if ((ph = p.hash) > h)
                    dir = -1;
                else if (ph < h)
                    dir = 1;
                else if ((kc == null &&
                          (kc = comparableClassFor(k)) == null) ||
                         (dir = compareComparables(kc, k, pk)) == 0)
                    dir = tieBreakOrder(k, pk); // 打破平局
                
                TreeNode<K,V> xp = p;
                if ((p = (dir <= 0) ? p.left : p.right) == null) {
                    x.parent = xp;
                    if (dir <= 0)
                        xp.left = x;
                    else
                        xp.right = x;
                    root = balanceInsertion(root, x); // 平衡插入
                    break;
                }
            }
        }
    }
    moveRootToFront(tab, root); // 確保根節點在桶的第一個位置
}

4.2 紅黑樹平衡操作

紅黑樹的平衡是通過復雜的旋轉和重新著色實現的:

static <K,V> TreeNode<K,V> balanceInsertion(TreeNode<K,V> root,
                                            TreeNode<K,V> x) {
    x.red = true; // 新插入的節點總是紅色
    
    for (TreeNode<K,V> xp, xpp, xppl, xppr;;) {
        if ((xp = x.parent) == null) {
            x.red = false; // 根節點必須為黑色
            return x;
        }
        else if (!xp.red || (xpp = xp.parent) == null)
            return root;
        
        if (xp == (xppl = xpp.left)) {
            if ((xppr = xpp.right) != null && xppr.red) {
                // 情況1:叔叔節點是紅色
                xppr.red = false;
                xp.red = false;
                xpp.red = true;
                x = xpp;
            }
            else {
                if (x == xp.right) {
                    // 情況2:x是右孩子,需要左旋轉
                    root = rotateLeft(root, x = xp);
                    xpp = (xp = x.parent) == null ? null : xp.parent;
                }
                if (xp != null) {
                    // 情況3:x是左孩子,需要右旋轉并重新著色
                    xp.red = false;
                    if (xpp != null) {
                        xpp.red = true;
                        root = rotateRight(root, xpp);
                    }
                }
            }
        }
        else {
            // 對稱的情況處理...
        }
    }
}

五、為什么不是7或9?

5.1 排除閾值7的理由

如果閾值設為7,會帶來以下問題:

1. 過度樹化:鏈表長度7的概率是8的15倍左右,會導致頻繁的樹化操作

2. 內存浪費:紅黑樹節點內存開銷是鏈表節點的約2倍

3. 性能下降:對于短鏈表,遍歷可能比樹查找更快

// 閾值7 vs 8的概率對比
public class ThresholdComparison {
    public static void main(String[] args) {
        double lambda = 0.5;
        
        double prob7 = poissonProbability(lambda, 7);
        double prob8 = poissonProbability(lambda, 8);
        double prob9 = poissonProbability(lambda, 9);
        
        System.out.println("長度7的概率: " + prob7);
        System.out.println("長度8的概率: " + prob8); 
        System.out.println("長度9的概率: " + prob9);
        
        System.out.println("7比8高 " + (prob7 / prob8) + " 倍");
        System.out.println("7比9高 " + (prob7 / prob9) + " 倍");
    }
    
    private static double poissonProbability(double lambda, int k) {
        return Math.exp(-lambda) * Math.pow(lambda, k) / factorial(k);
    }
    
    private static long factorial(int n) {
        long result = 1;
        for (int i = 2; i <= n; i++) {
            result *= i;
        }
        return result;
    }
}

5.2 排除閾值9的理由

閾值9的問題同樣明顯:

1. 風險容忍度:在哈希攻擊場景下,長度為9的鏈表性能已經明顯下降

2. 邊際收益遞減:從8增加到9帶來的性能提升有限

3. 實際需求:在正常使用情況下,長度8已經足夠罕見

5.3 閾值8的黃金平衡

閾值8在各方面達到了最佳平衡:

概率合理性:千萬分之六的概率在工程上可接受

性能優化:在真正需要時提供O(log n)性能保障

資源效率:避免不必要的內存和計算開銷

六、實際應用場景與測試驗證

6.1 哈希攻擊防護

樹化機制的一個重要應用場景是防護哈希碰撞攻擊:

public class HashAttackProtection {
    
    public static void testHashCollision() {
        HashMap<WeakKey, String> map = new HashMap<>();
        
        // 創建大量具有相同哈希碼的鍵
        List<WeakKey> keys = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            WeakKey key = new WeakKey(i, 123); // 所有鍵具有相同哈希碼
            keys.add(key);
            map.put(key, "value" + i);
        }
        
        // 測試查詢性能
        long startTime = System.nanoTime();
        for (WeakKey key : keys) {
            map.get(key);
        }
        long duration = System.nanoTime() - startTime;
        
        System.out.println("哈希沖突場景查詢時間: " + duration + " ns");
        System.out.println("桶結構: " + getBucketStructure(map));
    }
    
    static class WeakKey {
        final int id;
        final int hash; // 固定哈希碼
        
        WeakKey(int id, int hash) {
            this.id = id;
            this.hash = hash;
        }
        
        @Override
        public int hashCode() {
            return hash; // 故意制造哈希沖突
        }
        
        @Override
        public boolean equals(Object obj) {
            if (this == obj) return true;
            if (obj == null || getClass() != obj.getClass()) return false;
            WeakKey weakKey = (WeakKey) obj;
            return id == weakKey.id;
        }
    }
    
    private static String getBucketStructure(HashMap<?, ?> map) {
        // 通過反射獲取內部結構信息(實際中不推薦)
        try {
            Field tableField = HashMap.class.getDeclaredField("table");
            tableField.setAccessible(true);
            Object[] table = (Object[]) tableField.get(map);
            
            for (Object node : table) {
                if (node != null) {
                    int length = getChainLength(node);
                    if (length >= 8) {
                        return "紅黑樹 (長度: " + length + ")";
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "鏈表";
    }
    
    private static int getChainLength(Object node) {
        int length = 0;
        while (node != null) {
            length++;
            try {
                Field nextField = node.getClass().getDeclaredField("next");
                nextField.setAccessible(true);
                node = nextField.get(node);
            } catch (Exception e) {
                break;
            }
        }
        return length;
    }
}

6.2 性能基準測試

通過實際測試驗證不同閾值選擇的性能影響:

public class ThresholdBenchmark {
    
    private static final int TEST_SIZE = 100000;
    
    public static void main(String[] args) {
        System.out.println("測試不同鏈表長度下的性能表現:");
        System.out.println("長度\t鏈表查詢\t樹查詢\t優勢比");
        System.out.println("----------------------------------------");
        
        for (int length = 1; length <= 15; length++) {
            long listTime = testLinkedList(length);
            long treeTime = testRedBlackTree(length);
            double ratio = (double) listTime / treeTime;
            
            System.out.printf("%d\t%d ns\t%d ns\t%.2f", 
                length, listTime, treeTime, ratio);
            
            if (length == 8) System.out.print(" ← 當前閾值");
            System.out.println();
        }
    }
    
    private static long testLinkedList(int length) {
        LinkedList<Integer> list = new LinkedList<>();
        for (int i = 0; i < length; i++) {
            list.add(i);
        }
        
        long startTime = System.nanoTime();
        for (int i = 0; i < 10000; i++) {
            list.contains(length - 1); // 查找最后一個元素
        }
        return (System.nanoTime() - startTime) / 10000;
    }
    
    private static long testRedBlackTree(int length) {
        TreeSet<Integer> tree = new TreeSet<>();
        for (int i = 0; i < length; i++) {
            tree.add(i);
        }
        
        long startTime = System.nanoTime();
        for (int i = 0; i < 10000; i++) {
            tree.contains(length - 1);
        }
        return (System.nanoTime() - startTime) / 10000;
    }
}

七、其他相關設計考量

7.1 取消樹化閾值6的設計

HashMap不僅設置了樹化閾值8,還設置了取消樹化閾值6:

static final int UNTREEIFY_THRESHOLD = 6;

這種設計避免了在閾值附近頻繁的樹化-取消樹化振蕩:

1. ** hysteresis現象**:使用不同的閾值提供穩定性

2. 性能考慮:避免頻繁的結構轉換開銷

3. 工程實踐:在系統設計中常見的防抖動策略

7.2 最小樹化容量要求

HashMap還設置了最小樹化容量,防止在小表中過早樹化:

static final int MIN_TREEIFY_CAPACITY = 64;

這種設計確保了:

  • ? 只有在哈希表足夠大時才進行樹化
  • ? 小表優先通過擴容解決沖突
  • ? 避免在小規模場景下的過度優化

結論

HashMap選擇8作為鏈表轉紅黑樹的閾值,是基于深刻的數學原理、性能分析和工程實踐的完美結合。這一設計決策體現了以下幾個關鍵點:

1. 數學嚴謹性:基于泊松分布的概率計算,確保在正常情況下樹化極少發生

2. 性能最優化:在鏈表性能開始顯著下降的臨界點引入樹結構

3. 資源效率:平衡了內存開銷和計算性能的權衡

4. 工程實用性:考慮了實際應用場景和極端情況下的表現

閾值8的選擇不是任意的,而是經過精心計算和實踐驗證的最佳平衡點。它既提供了對哈希碰撞攻擊的有效防護,又避免了在正常使用場景下的不必要的性能開銷。這種細致入微的設計正是Java集合框架成熟性和專業性的體現,也為我們在日常開發中的性能優化提供了寶貴的參考范例。

通過深入理解這一設計決策背后的原理,我們不僅能夠更好地使用HashMap,還能從中學習到系統設計和性能優化的寶貴經驗,這些經驗可以應用于我們日常開發的各個方面。

責任編輯:武曉燕 來源: 程序員秋天
相關推薦

2020-08-19 16:36:53

HashMap紅黑樹閾值

2019-09-24 09:33:53

MySQLB+樹InnoDB

2013-03-25 10:14:18

NginxApache

2019-04-19 11:56:48

框架AI開發

2012-10-10 16:52:21

CentOSDebianUbuntu

2021-10-30 19:57:00

HTTP2 HTTP

2021-08-14 09:04:58

TypeScriptJavaScript開發

2020-09-15 09:23:19

C++WindowsC#

2017-09-11 19:58:06

PostgreSQLMySQL數據庫

2020-06-02 14:17:55

QWER排列鍵盤打印機

2025-07-31 03:00:00

數據湖BLMLLM

2021-02-26 05:30:25

元素For-Each代碼

2023-11-02 08:20:54

SocketZygoteAndroid

2021-06-30 12:47:12

標簽HTML分辨率

2021-03-26 11:50:28

Linuxexals

2023-03-01 10:42:58

gRPC服務端設置

2021-12-02 09:20:33

TCPLinux三次握手

2016-10-11 11:13:15

Linus Torva

2023-01-11 12:14:50

NeoVimVim開發

2024-03-22 12:29:03

HashMap線程
點贊
收藏

51CTO技術棧公眾號

欧美一区二区在线| 亚洲人成电影在线播放| 男人添女荫道口女人有什么感觉| 亚洲av综合色区无码一二三区 | 成人丝袜高跟foot| 日本久久久久亚洲中字幕| 免费看一级黄色| 爱爱精品视频| 欧美婷婷六月丁香综合色| 色婷婷777777仙踪林| 欧美成人综合在线| 精品一区二区久久| 57pao成人国产永久免费| 亚洲欧美另类日本| 欧美日韩一道本| www夜片内射视频日韩精品成人| 99热精品在线观看| www日韩中文字幕在线看| 成年女人免费视频| 国产精品成人3p一区二区三区| 欧美性生交大片免费| 国产卡一卡二在线| seseavlu视频在线| 91视频www| 懂色中文一区二区三区在线视频| 日本丰满少妇做爰爽爽| 一区二区国产精品| 欧美激情视频在线观看| 日韩三级在线观看视频| 国产毛片一区二区三区| 亚洲第一福利视频| 国产ts在线观看| 动漫一区二区三区| 欧美性受xxxx| 国产福利一区视频| 黄视频网站在线观看| 一区二区三区精品在线观看| 自拍偷拍视频在线| 在线免费观看黄色av| 久久久久99精品一区| 精品免费视频123区| 亚洲欧美另类视频| 国产精品66部| 92国产精品视频| 国产精品久久久久久无人区| 久久精品国产秦先生| 国产精品v片在线观看不卡| 亚洲国产精品无码久久久| 日韩一区二区久久| 91禁国产网站| 日产精品久久久| 在线视频精品| 青青草原一区二区| 五月天婷婷导航| 久久婷婷丁香| 国产精品日韩在线观看| 欧美性受xxx黑人xyx性爽| 日韩精品欧美成人高清一区二区| 日产精品久久久一区二区福利| 天天做天天爱夜夜爽| 亚洲深夜av| 人人澡人人澡人人看欧美| 久久精品久久久久久久| 日本美女一区二区| 成人日韩av在线| 国产视频手机在线观看| 国产精品一二一区| 国产乱码一区| 天堂资源最新在线| 国产午夜精品在线观看| 亚洲国产欧美日韩| 国产一二区在线观看| 亚洲人成在线播放网站岛国| 毛片在线视频观看| 天堂av中文在线观看| 欧美一a一片一级一片| www.久久av.com| 亚洲精品国产九九九| 亚洲国内精品视频| 在线看片中文字幕| 亚洲精品午夜av福利久久蜜桃| 久久久久免费视频| 欧美 日韩 精品| 精品一区二区三区视频| 国产在线一区二区三区欧美| 国产乱理伦片a级在线观看| 最新久久zyz资源站| 喜爱夜蒲2在线| 中文字幕在线直播| 欧美精品丝袜久久久中文字幕| 人妻 丝袜美腿 中文字幕| 丝袜av一区| 日韩视频欧美视频| 99热只有这里有精品| 久久99日本精品| 久久精品二区| 乱人伦中文视频在线| 夜夜嗨av一区二区三区中文字幕| 免费在线激情视频| 久久久久久久久久久久电影| 国产丝袜高跟一区| 五月婷婷一区二区| 视频在线观看一区| 国产富婆一区二区三区| 97在线观看免费观看高清| 亚洲成人免费看| 男人的天堂最新网址| 牛牛精品成人免费视频| 久久精品国产91精品亚洲| 午夜精品久久久久久久久久久久久蜜桃 | 亚洲性猛交xxxxwww| 中文字幕在线观看成人 | 亚洲成人激情小说| 精品国产乱码久久久久久蜜坠欲下 | 欧美精品三级在线| 一区二区三区www| 日本三级视频在线| 国产在线不卡视频| 色大师av一区二区三区| av免费在线视| 日韩一区二区精品| 美女三级黄色片| 肉丝袜脚交视频一区二区| 国产精品日韩二区| 性直播体位视频在线观看| 欧美日韩国产精品成人| a毛片毛片av永久免费| 亚洲精品九九| 国产精品国产精品国产专区蜜臀ah | 久久久免费精品视频| 97久久人国产精品婷婷| 国产日产精品1区| 男人靠女人免费视频网站| 一本色道69色精品综合久久| 久久精品影视伊人网| 免费黄色一级大片| 国产午夜三级一区二区三| 女人扒开屁股爽桶30分钟| 日本成人中文| 777午夜精品福利在线观看| 高清毛片aaaaaaaaa片| 亚洲精品国产成人久久av盗摄| 亚洲最大天堂网| 久久中文字幕av| 成人av番号网| 欧美jizzhd欧美| 欧美精品一二三| 视频这里只有精品| 国产乱码精品一区二区三区五月婷| 一区二区三区欧美在线| 五月天色综合| 久久成人人人人精品欧| jizz中国少妇| 亚洲午夜激情av| 99久久国产精| 噜噜噜91成人网| 香蕉久久夜色| 国产va免费精品观看精品| 欧美成年人在线观看| 国产xxxx孕妇| 一区二区三区在线看| 日本性生活一级片| 99精品国产福利在线观看免费| 韩国成人av| 精品日韩视频| 最近2019中文字幕第三页视频| 伊人网综合在线| 日韩毛片精品高清免费| 国产chinesehd精品露脸| 亚洲性图久久| 免费毛片一区二区三区久久久| 日韩新的三级电影| 久久久精品电影| 国产 日韩 欧美 精品| 狠狠躁天天躁日日躁欧美| 四虎国产精品成人免费入口| 韩国毛片一区二区三区| 欧美精品久久久久久久自慰 | 亚洲欧美日韩第一区| 中文字幕视频一区二区| 亚洲精品日韩一| 精品人妻一区二区三区日产乱码卜| 日韩不卡免费视频| 97精品国产97久久久久久粉红| 加勒比色老久久爱综合网| 国产成人啪精品视频免费网| 超碰超碰在线| 亚洲乱码一区二区| 国产av一区二区三区精品| 精品国产成人av| 蜜桃av免费观看| www.亚洲免费av| 国产野外作爱视频播放| 激情婷婷亚洲| 新呦u视频一区二区| 国产成人一二片| 国产伦精品免费视频| 丰乳肥臀在线| 色婷婷综合久久久久| 人妻少妇精品无码专区久久| 欧美日韩小视频| 国产又大又黑又粗免费视频| 日本一区二区成人| av2014天堂网| 国产精品夜夜爽| 国产精品天天av精麻传媒| 一区在线视频观看| 一本色道久久综合亚洲精品婷婷| 美国一区二区| 亚洲最大福利视频网| 国产一区二区主播在线| 国产91ⅴ在线精品免费观看| 亚洲无线看天堂av| 日韩在线视频国产| 日本福利在线观看| 精品三级在线观看| 97在线视频人妻无码| 在线亚洲免费视频| 日韩激情在线播放| 一区2区3区在线看| 成年人二级毛片| 国产精品女上位| 一区二区三区四区免费| 99麻豆久久久国产精品免费| 久久久国产精品久久久| 国产在线麻豆精品观看| xx欧美撒尿嘘撒尿xx| 久久最新视频| 大肉大捧一进一出好爽动态图| 亚洲黄色天堂| 日本福利视频一区| 国内久久精品| 免费视频爱爱太爽了| 欧美三级第一页| 91精品一区二区三区四区| 我不卡影院28| 国产又爽又黄ai换脸| 水蜜桃精品av一区二区| 亚洲资源在线网| 欧美丰满日韩| 中文字幕久久综合| 国产精品99视频| 在线视频一二三区| 欧美在线黄色| 黄色一级大片免费| 欧美午夜免费影院| www污在线观看| 亚洲乱亚洲高清| 免费av观看网址| 蜜桃av综合| 国产一线二线三线在线观看| 日产国产欧美视频一区精品| 一级黄色特级片| 九九视频精品免费| 欧美日韩一区二区区别是什么| 国产超碰在线一区| 美女搡bbb又爽又猛又黄www| av中文字幕亚洲| 成年人免费观看视频网站 | 亚洲片国产一区一级在线观看| 你懂的在线观看| 宅男66日本亚洲欧美视频| 免费超碰在线| 欧美大片在线免费观看| 九九色在线视频| 欧美一级视频在线观看| 日韩国产网站| 不卡一卡2卡3卡4卡精品在| 成人自拍在线| 日本一区二区在线视频| 999国产精品视频| 97中文字幕在线| 性感少妇一区| 久久久久久久久久久久久久久国产| 国产一区二区三区四区五区入口 | 久久久久久久久久久久久久国产| 奇米在线7777在线精品 | 一级黄色a毛片| 日韩欧美色综合网站| 午夜在线视频免费| 日韩中文字幕精品| 黄网在线免费看| 国产激情视频一区| 日韩av综合| 免费成人看片网址| 亚洲视频在线免费| 男人天堂网视频| 国产一区二区三区免费看| 私密视频在线观看| 亚洲国产高清aⅴ视频| 国产一级av毛片| 在线亚洲高清视频| 亚洲免费黄色片| 色哟哟入口国产精品| √天堂8资源中文在线| 国产日韩视频在线观看| 麻豆一区二区麻豆免费观看| 国产又黄又爽免费视频| 性欧美精品高清| 女同性αv亚洲女同志| 国产精品女主播av| 国产精品久免费的黄网站| 欧美一区二区精美| 成人欧美亚洲| 777午夜精品福利在线观看| 日韩激情精品| 亚洲狠狠婷婷综合久久久| 亚洲一区欧美激情| 师生出轨h灌满了1v1| 国产精品美女久久久久久久| 国产原创视频在线| 欧美xxxx在线观看| 免费黄色在线观看| 国产精品久久久久免费a∨大胸| 久久动漫网址| 国产一级做a爰片久久毛片男| 另类专区欧美蜜桃臀第一页| 欧美做受高潮6| 午夜视频在线观看一区二区| 国产免费黄色网址| 自拍偷拍亚洲在线| 天天免费亚洲黑人免费| 精品国产免费人成电影在线观...| 欧美三级特黄| 久草福利在线观看| 亚洲欧洲综合另类| 在线视频1卡二卡三卡| 亚洲性xxxx| 久久91导航| 欧美专区一二三| 久久精品道一区二区三区| 538国产视频| 天天色综合天天| 日韩在线视频观看免费| 欧美精品久久久久久久久久| 久久99精品久久久野外观看| 国产精品无码乱伦| 国产美女视频91| 成人免费视频网站入口::| 欧美精品欧美精品系列| 免费观看在线午夜影视| 91精品久久久久久久久中文字幕 | 免费日韩中文字幕| 久久久亚洲高清| 无码人妻丰满熟妇奶水区码| 国产亚洲欧洲高清| 九九九伊在线综合永久| 亚洲欧美在线网| 九九在线精品视频| 欧美日韩综合一区二区| 日韩欧美一区二区不卡| 免费看电影在线| 久久久水蜜桃| 视频一区视频二区中文字幕| 久久久精品成人| 欧美精品777| 色www永久免费视频首页在线| 国外成人免费视频| 久久成人在线| 亚洲不卡的av| 欧美一区二区高清| ****av在线网毛片| 欧美污视频久久久| 蜜桃久久精品一区二区| 午夜三级在线观看| 日韩免费观看高清完整版 | 国产区欧美区日韩区| 免费在线成人| 国产小视频你懂的| 精品久久久久久亚洲综合网 | 激情成人综合| 日本高清www| 欧美另类videos死尸| 免费污视频在线观看| 欧美一区二区高清在线观看| 久久精品久久综合| 国语对白一区二区| 亚洲视频在线观看视频| 日韩欧美激情电影| 成年人在线看片| 亚洲精品乱码久久久久久黑人| 亚洲av电影一区| 成人免费看黄网站| 亚洲欧洲日本一区二区三区| jizz中文字幕| 日韩欧美一区二区免费| 电影天堂国产精品| a天堂资源在线观看| 欧美激情中文不卡| 亚洲精品18p| 国产日韩av在线播放| 亚洲韩日在线| 国产一二三四区| 国产亚洲欧美日韩一区二区| 丁香一区二区| 不卡的在线视频| 狠狠躁夜夜躁久久躁别揉| 动漫一区在线| 茄子视频成人在线观看| 成人禁用看黄a在线|