精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

福利一区视频| 婷婷视频在线观看| 欧美精品国产一区| 欧美精品一区二区三| 国内自拍在线观看| 色欧美激情视频在线| 国产麻豆精品在线观看| 色综合视频一区中文字幕| 五月开心播播网| 国产黄色一区| 第一福利永久视频精品| 亚洲国产日韩综合一区| 亚洲国产精品久久久久爰性色| 亚洲一区日韩| 欧美成人激情图片网| 一区二区三区免费在线观看视频| 91视频成人| 一本色道久久综合亚洲aⅴ蜜桃| 最近看过的日韩成人| 五月婷婷六月丁香| 黑人精品欧美一区二区蜜桃| 69久久夜色精品国产69乱青草| 成人黄色短视频| 丝袜连裤袜欧美激情日韩| 欧美日本一区二区在线观看| 一区二区传媒有限公司| 亚洲制服国产| 国产精品三级电影| 久久久久天天天天| 亚洲精品无遮挡| 国内精品久久久久影院一蜜桃| 欧洲s码亚洲m码精品一区| 青春草免费视频| 99久久久久国产精品| 亚洲免费电影一区| 动漫美女无遮挡免费| 精品国产亚洲日本| 欧美日韩激情在线| 中文字幕第21页| 热三久草你在线| 亚洲一区二区三区在线播放| 丰满女人性猛交| 中文日本在线观看| 国产午夜亚洲精品羞羞网站| 久久国产精品亚洲va麻豆| 亚洲精品久久久久久久久久| 国产美女在线精品| 成人激情视频在线播放| www.av88| 日韩av网站在线观看| 欧美一区二区三区四区在线| 五月婷婷激情网| 国产专区一区| 久久久在线视频| 日本三级欧美三级| 在线视频观看日韩| 97在线精品国自产拍中文| 久久99久久久| 国产一区日韩欧美| 欧美激情一区二区三级高清视频| 1024手机在线视频| 国产精品va| 久久全球大尺度高清视频| 国产无码精品视频| 国产日韩高清一区二区三区在线| 久久全国免费视频| 好看的av在线| 日韩二区在线观看| 国产一区二区视频在线观看| 91精东传媒理伦片在线观看| 国产在线观看一区二区| 7777精品伊久久久大香线蕉语言| 国产精品久久久久久久一区二区| 国产综合一区二区| 产国精品偷在线| 亚洲 欧美 激情 小说 另类| 久久综合久久综合久久| 日韩免费av一区二区三区| 日本www在线| 亚洲最大色网站| 青青艹视频在线| 成人国产在线| 日韩欧美黄色影院| 超碰男人的天堂| 国产精品免费大片| 久久精品国产久精国产一老狼| 欧美日韩在线国产| 国产日本精品| 成人黄色免费片| 女人18毛片水真多18精品| 久久蜜桃香蕉精品一区二区三区| 亚洲人成影视在线观看| 女同视频在线观看| 欧美亚洲一区三区| 日本成人在线免费| 少妇精品久久久一区二区| 精品国产一区二区三区久久狼5月 精品国产一区二区三区久久久狼 精品国产一区二区三区久久久 | 国产精品二线| 亚洲一区二区在线免费看| 凹凸国产熟女精品视频| 伊人久久一区| 亚洲欧美国产视频| 青青草在线观看视频| 六月婷婷一区| 99久久一区三区四区免费| 免费福利在线视频| 一区二区三区免费网站| 日本爱爱免费视频| 精品国内亚洲2022精品成人| 日韩视频欧美视频| 特黄视频免费看| 国产成人免费在线视频| 亚洲一区二区三区午夜| 蜜桃视频m3u8在线观看| 欧美一区二区三区视频免费播放| 久久精品老司机| 欧美三级在线| 91麻豆国产精品| av资源网在线观看| 欧美性高潮在线| 国产在线观看免费播放| 色综合天天爱| 国产999精品久久久影片官网| 亚洲卡一卡二卡三| 亚洲乱码国产乱码精品精98午夜| 亚洲国产高清aⅴ视频| 国产日本欧美视频| 青青草免费观看免费视频在线| 亚洲综合区在线| 中文字幕第22页| 欧美xxav| 国产精品自产拍在线观看中文| 免费播放片a高清在线观看| 亚洲超丰满肉感bbw| 麻豆传媒在线看| 在线精品小视频| 成人免费淫片aa视频免费| 成年人在线免费观看| 色婷婷av一区二区三区大白胸 | xvideos亚洲人网站| 久久国产乱子伦精品| 91在线免费视频观看| 免费不卡av在线| 风间由美一区二区av101| x99av成人免费| 国产露脸国语对白在线| 亚洲欧洲在线观看av| 日韩成人精品视频在线观看| 国产精品国产一区| 国产在线高清精品| www在线免费观看视频| 日韩一区二区在线观看视频| 久久久久亚洲av无码专区体验| 国产精品一区二区三区四区| 青青草视频国产| 超碰精品在线| 欧美一级大胆视频| 每日更新av在线播放| 日本高清无吗v一区| 免费看的黄色录像| 国产一区在线不卡| 日韩黄色片在线| 日韩av中文字幕一区| 日本久久中文字幕| 亚洲第一av在线| 西西44rtwww国产精品| 91麻豆蜜桃一区二区三区| 精品久久久久久久免费人妻| 日韩欧美精品一区| 亚洲一区二区中文| 成人免费图片免费观看| 亚洲欧美国产一区二区三区| 中文字幕永久免费视频| 亚洲精品国产无天堂网2021| 日韩无码精品一区二区| 久久综合影音| 一区二区在线观看网站| 日韩欧美中文字幕一区二区三区| 久久久中精品2020中文| 国产三级电影在线观看| 欧美一级在线视频| 日本va欧美va国产激情| 国产精品私房写真福利视频| 最好看的中文字幕| 中文一区在线| 咪咪色在线视频| 欧美日韩一区二区三区在线电影| 国产精品白丝jk喷水视频一区| 超碰个人在线| 亚洲另类图片色| 国产毛片毛片毛片毛片| 天天影视网天天综合色在线播放| 蜜桃av乱码一区二区三区| 国产精品亚洲人在线观看| 黄色片视频在线免费观看| 99久久亚洲精品蜜臀| 精品国产一区二区三| 欧美视频免费看| 68精品久久久久久欧美| 国产视频在线播放| 日韩国产精品一区| 国产精品九九九九| 日韩欧美在线中文字幕| 91人妻一区二区三区蜜臀| 91婷婷韩国欧美一区二区| 久久久久xxxx| 葵司免费一区二区三区四区五区| 日韩亚洲欧美一区二区| 成人av二区| 久久偷窥视频| 大奶在线精品| 亚洲在线www| 看片一区二区| 国产97色在线| 伊人久久综合一区二区| 欧美黄色成人网| а√中文在线8| 色偷偷av一区二区三区乱| 色视频在线观看| 亚洲成人a**站| 精品国产av一区二区| 欧美日韩精品免费| 中文字幕永久在线| 欧美性生交大片免网| 亚洲精品在线观看av| 亚洲精品视频在线观看免费| 成人黄色短视频| 国产精品你懂的在线欣赏| 久久精品国产亚洲AV熟女| 北岛玲一区二区三区四区| 无码人妻一区二区三区在线视频| 久久国产精品第一页| 色婷婷成人在线| 男男成人高潮片免费网站| 无码人妻丰满熟妇区毛片| 99视频一区| 日韩av综合在线观看| 亚洲激情欧美| 日本a在线免费观看| 亚洲无线视频| 黄色一级片在线看| 亚洲网站在线| 欧美日韩性生活片| 国产日本精品| aaa毛片在线观看| 久久午夜视频| 日本成人在线免费视频| 久久一区欧美| 欧美一级黄色影院| 日本在线播放一区二区三区| 青青青在线视频免费观看| 日韩av不卡一区二区| jizz18女人| 国产美女视频91| 亚洲熟女一区二区三区| 成人午夜激情视频| 中文文字幕文字幕高清| 久久久久久久久一| 国产传媒在线看| 亚洲日本电影在线| 久久成人国产精品入口| 精品国产91久久久久久| 久久国产视频精品| 欧美午夜在线观看| 99精品久久久久久中文字幕 | 久久久久国产免费| eeuss鲁片一区二区三区在线观看| 欧美双性人妖o0| 国产亚洲精品超碰| 一级免费黄色录像| 亚洲综合男人的天堂| 国产午夜性春猛交ⅹxxx| 欧美制服丝袜第一页| 国产精品探花视频| 亚洲国产精品久久精品怡红院 | 久久视频在线直播| 丁香花电影在线观看完整版| 欧美在线观看网址综合| yy6080久久伦理一区二区| 999精品在线观看| 神马香蕉久久| 亚洲第一页在线视频| 伊人久久婷婷| 国产 porn| 国产99精品国产| a级片在线观看| 亚洲激情av在线| 婷婷激情五月综合| 欧美一区二区三区在线| 日夜干在线视频| 久热精品视频在线观看| 这里有精品可以观看| 91久久精品在线| 精品在线91| av在线com| 蜜乳av一区二区| 给我免费观看片在线电影的| 国产精品国产三级国产aⅴ入口| 国产一国产二国产三| 精品视频一区 二区 三区| 欧美熟妇交换久久久久久分类 | 精品国产区一区| av中文在线| 51午夜精品视频| 久久九九精品视频| 五月天国产一区| 国产一区二区三区成人欧美日韩在线观看 | 在线观看欧美激情| 99亚洲视频| 亚洲天堂小视频| 国产精品三级视频| 欧美日韩综合一区二区三区| 日韩美女一区二区三区| 亚洲视频tv| 国产精品678| 亚洲丁香日韩| a级黄色一级片| 丁香婷婷综合激情五月色| 亚洲一级二级片| 欧美三级在线看| 福利在线午夜| 日韩av毛片网| 日本一道高清一区二区三区| 国产一区二区四区| 国产乱人伦精品一区二区在线观看| 免费网站在线高清观看| 欧美日韩在线视频观看| 老牛影视av牛牛影视av| 九九热这里只有精品6| 91精品一久久香蕉国产线看观看| 天堂va久久久噜噜噜久久va| 久久一区欧美| 无码人妻aⅴ一区二区三区69岛| 精品高清美女精品国产区| 成人午夜免费福利| 欧美精品www| 99香蕉久久| av在线播放天堂| 成人午夜伦理影院| 国产一级片免费| 精品国产欧美一区二区| 日本孕妇大胆孕交无码| 91黄在线观看| 午夜天堂精品久久久久| 日本中文字幕精品| 一级特黄大欧美久久久| 亚洲AV无码一区二区三区少妇| 欧美黑人性视频| 国产精品久久久久av蜜臀| www.射射射| 91女厕偷拍女厕偷拍高清| 久久久久亚洲av成人毛片韩| 亚洲男人的天堂网站| 日韩av大片站长工具| 婷婷久久五月天| 国产伦精品一区二区三区免费| 青草影院在线观看| 日韩精品影音先锋| www.综合| 日韩在线三级| 国产在线不卡一区| 国产一级视频在线| 日韩av在线精品| 成人在线黄色| 中文字幕の友人北条麻妃| 高清av一区二区| 一级成人黄色片| 色阁综合伊人av| 2023国产精华国产精品| 国产免费黄色一级片| 国产视频一区在线播放| 一本一道精品欧美中文字幕| 久精品免费视频| 欧美日韩一本| 亚洲第一天堂久久| 亚洲国产日韩综合久久精品| 女人天堂在线| 91香蕉电影院| 国产视频一区三区| 国产jizz18女人高潮| 精品国产乱码久久久久久闺蜜| 欧美电影网站| 特级黄色录像片| 久久天堂av综合合色蜜桃网| 一区二区日韩视频| 久久久在线免费观看| 欧美亚洲国产激情| 国产免费a级片| 欧美精品在线一区二区| 超碰中文在线| 亚洲国产午夜伦理片大全在线观看网站| 国产一区不卡在线| 极品国产91在线网站| 欧美精品免费在线观看| 国产99精品| 亚洲国产精品狼友在线观看| 欧美性大战久久久| caoporn视频在线| 国产高清免费在线| 久久久久久久久97黄色工厂|