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

Stream很好,Map很酷,但答應我別用toMap()!

開發 前端
toMap () 是一個強大的工具,但也是一個危險的工具。它的簡單易用性可能會掩蓋潛在的問題,導致代碼在生產環境中出現意想不到的錯誤。因此,在使用 toMap () 時,一定要謹慎處理重復鍵、null 值和性能問題,或者選擇更合適的替代方案。?

兄弟們,今天咱們來聊聊 Java Stream 里那個看似人畜無害的 toMap () 方法。這貨就像個表面乖巧的二哈,平時賣萌撒嬌樣樣在行,但一不留神就給你拆家 —— 哦不,是讓你的代碼在生產環境里炸鍋。

先別急著反駁,我知道你們肯定用過類似這樣的代碼:

List<User> users = ...;
Map<Long, User> userMap = users.stream().collect(Collectors.toMap(User::getId, Function.identity()));

這行代碼看起來人畜無害,甚至還挺優雅。但如果 users 里有兩個用戶的 id 相同呢?恭喜你,喜提IllegalStateException: Duplicate key異常一枚。這就好比你去餐廳點餐,服務員說 “我們這兒的漢堡包保證獨一無二”,結果端上來兩個一模一樣的,你說氣不氣?更坑的是,toMap () 的 “坑” 遠不止這一個。比如,當你想把 List 轉成 Map 時,發現 value 可能為 null,這時候 toMap () 會直接拋出 NPE,連個解釋的機會都不給你。再比如,當你在并行流中使用 toMap () 時,可能會遇到線程安全問題,導致數據混亂。這些問題就像隱藏在代碼里的定時炸彈,隨時可能讓你的程序 “boom” 的一聲爆炸。

一、toMap () 的三大致命傷

1. 重復鍵:雙胞胎鍵的世紀難題

(1)默認行為:一視同仁,直接炸毛

toMap () 的默認行為是,如果遇到重復的鍵,就直接拋出IllegalStateException。這就好比你在玩消消樂,好不容易湊齊三個相同的元素,結果游戲直接閃退了。這種設計在大多數情況下是合理的,因為 Map 的鍵必須唯一。但在實際開發中,數據重復的情況并不少見,比如從數據庫查詢數據時,可能會因為業務邏輯問題導致重復記錄。

舉個栗子:

List<Product> products = Arrays.asList(
    new Product(1L, "蘋果"),
    new Product(1L, "香蕉")
);
Map<Long, String> productMap = products.stream()
    .collect(Collectors.toMap(Product::getId, Product::getName));

這段代碼會拋出Duplicate key異常,因為兩個 Product 對象的 id 都是 1L。這時候,你可能會想:“我只是想保留最后一個出現的值,或者合并它們,難道就這么難嗎?”

(2)合并策略:教 toMap () 做人

為了應對重復鍵的問題,toMap () 提供了一個三參數的重載方法,允許你自定義合并策略。例如,你可以選擇保留舊值、替換新值,或者將兩個值合并。

  • 保留舊值:
Map<Long, String> productMap = products.stream()
    .collect(Collectors.toMap(
        Product::getId,
        Product::getName,
        (oldValue, newValue) -> oldValue // 保留舊值
    ));
  • 替換新值:
Map<Long, String> productMap = products.stream()
    .collect(Collectors.toMap(
        Product::getId,
        Product::getName,
        (oldValue, newValue) -> newValue // 替換新值
    ));
  • 合并值:
Map<Long, String> productMap = products.stream()
    .collect(Collectors.toMap(
        Product::getId,
        Product::getName,
        (oldValue, newValue) -> oldValue + "," + newValue // 合并值
    ));

這樣,當遇到重復鍵時,toMap () 就會按照你定義的合并策略來處理,而不是直接拋出異常。但問題來了,這種方法需要你在代碼中顯式處理重復鍵,增加了代碼的復雜性。而且,如果你的業務邏輯比較復雜,合并策略可能會變得難以維護。

2. null 值:隱形殺手

(1)鍵為 null:Map 的禁區

Map 的鍵是不允許為 null 的(HashMap 允許,但 ConcurrentHashMap 不允許)。如果你在使用 toMap () 時,某個元素的鍵映射結果為 null,就會拋出NullPointerException。

舉個栗子:

List<User> users = Arrays.asList(
    new User(null, "張三"),
    new User(1L, "李四")
);
Map<Long, String> userMap = users.stream()
    .collect(Collectors.toMap(User::getId, User::getName));

這段代碼會拋出NullPointerException,因為第一個 User 對象的 id 為 null。這時候,你可能會想:“我只是想過濾掉 id 為 null 的用戶,難道就這么難嗎?”

(2)值為 null:無聲的陷阱

Map 的值是允許為 null 的,但在某些情況下,值為 null 可能會導致后續操作出現問題。例如,當你使用map.get(key)獲取值時,如果值為 null,就需要進行判空處理。

舉個栗子:

List<User> users = Arrays.asList(
    new User(1L, null),
    new User(2L, "李四")
);
Map<Long, String> userMap = users.stream()
    .collect(Collectors.toMap(User::getId, User::getName));
String name = userMap.get(1L); // name為null,需要判空

為了避免這種情況,你可以在映射值時進行非空處理,或者在收集完成后過濾掉值為 null 的鍵值對。

3. 性能問題:并行流中的 “陷阱”

(1)并行流的 “甜蜜陷阱”

Stream 的并行流可以充分利用多核 CPU 的優勢,提高數據處理效率。但在使用 toMap () 時,并行流可能會導致性能問題,甚至數據混亂。

舉個栗子:

List<User> users = generateLargeUserList(10_000_000);
Map<Long, User> userMap = users.parallelStream()
    .collect(Collectors.toMap(User::getId, Function.identity()));

這段代碼在并行流中使用 toMap (),可能會因為線程安全問題導致數據混亂。因為 toMap () 默認使用的是 HashMap,而 HashMap 在多線程環境下是非線程安全的。這時候,你可能會想:“我只是想提高處理效率,難道就這么難嗎?”

(2)解決方案:toConcurrentMap ()

為了解決并行流中的線程安全問題,Java 提供了Collectors.toConcurrentMap()方法。這個方法返回的是 ConcurrentHashMap,支持并發操作,性能更好。

舉個栗子:

Map<Long, User> userMap = users.parallelStream()     .collect(Collectors.toConcurrentMap(User::getId, Function.identity()));

這樣,即使在并行流中使用 toConcurrentMap (),也能保證數據的一致性和線程安全。但需要注意的是,toConcurrentMap () 的性能并不一定比 toMap () 好,具體取決于數據量和并發程度。

二、替代方案:toMap () 的 “平替” 們

既然 toMap () 有這么多坑,那有沒有更好的替代方案呢?答案是肯定的。下面,我將為大家介紹幾種常用的替代方法。

1. groupingBy:分組處理的 “瑞士軍刀”

(1)基本用法:按字段分組

Collectors.groupingBy()是一個非常強大的收集器,它可以將流中的元素按照某個字段進行分組,返回一個 Map,其中鍵是分組字段的值,值是該分組下的元素列表。

舉個栗子:

List<Order> orders = ...;
Map<String, List<Order>> orderMap = orders.stream()
    .collect(Collectors.groupingBy(Order::getUserId));

這樣,orderMap 的鍵是用戶 id,值是該用戶的所有訂單列表。這種方法不僅可以避免重復鍵的問題,還可以方便地進行后續的統計和分析。

(2)進階用法:多級分組

groupingBy () 還支持多級分組,即先按一個字段分組,再按另一個字段分組,返回一個嵌套的 Map。

舉個栗子:

Map<String, Map<String, List<Order>>> orderMap = orders.stream()
    .collect(Collectors.groupingBy(
        Order::getUserId,
        Collectors.groupingBy(Order::getStatus)
    ));

這樣,orderMap 的結構是Map<用戶id, Map<訂單狀態, List<訂單>>>,可以方便地統計每個用戶不同狀態的訂單數量。

(3)統計聚合:與其他收集器結合

groupingBy () 還可以與其他收集器結合使用,進行統計聚合操作。例如,統計每個用戶的訂單總數、總金額等。

舉個栗子:

Map<String, Long> orderCountMap = orders.stream()
    .collect(Collectors.groupingBy(
        Order::getUserId,
        Collectors.counting()
    ));

Map<String, Double> totalAmountMap = orders.stream()
    .collect(Collectors.groupingBy(
        Order::getUserId,
        Collectors.summingDouble(Order::getAmount)
    ));

這樣,orderCountMap 的鍵是用戶 id,值是該用戶的訂單總數;totalAmountMap 的鍵是用戶 id,值是該用戶的訂單總金額。

2. toMap 的安全變種:處理重復鍵和 null 值

(1)處理重復鍵:三參數 toMap ()

前面已經介紹過,toMap () 的三參數重載方法可以自定義合并策略,處理重復鍵的問題。例如,保留舊值、替換新值或合并值。

(2)處理 null 值:過濾或默認值

為了避免鍵或值為 null 的問題,可以在流處理過程中進行過濾,或者在映射時提供默認值。

  • 過濾 null 鍵:
Map<Long, String> userMap = users.stream()
    .filter(user -> user.getId() != null)
    .collect(Collectors.toMap(User::getId, User::getName));
  • 提供默認值:
Map<Long, String> userMap = users.stream()
    .collect(Collectors.toMap(
        User::getId,
        User::getName,
        (oldValue, newValue) -> oldValue,
        () -> new HashMap<>()
    ));

這里,第四個參數() -> new HashMap<>()是一個 Map 的供應商,用于指定返回的 Map 類型。如果不指定,默認返回的是 HashMap。

3. 自定義收集器:靈活應對復雜需求

(1)為什么需要自定義收集器?

雖然 Java 提供的內置收集器已經能夠滿足大多數需求,但在某些情況下,我們可能需要更靈活的收集邏輯。例如,將流中的元素收集到一個自定義的 Map 中,或者在收集過程中進行復雜的轉換和聚合操作。

(2)自定義收集器的實現步驟

自定義收集器需要實現Collector接口,該接口定義了四個方法:supplier()、accumulator()、combiner()和finisher(),以及一個characteristics()方法。

舉個栗子:

public class CustomCollector<T, K, V> implements Collector<T, Map<K, V>, Map<K, V>> {
    privatefinalFunction<T, K> keyMapper;
    privatefinalFunction<T, V> valueMapper;
    privatefinal BinaryOperator<V> mergeFunction;

    public CustomCollector(Function<T, K> keyMapper, Function<T, V> valueMapper, BinaryOperator<V> mergeFunction) {
        this.keyMapper = keyMapper;
        this.valueMapper = valueMapper;
        this.mergeFunction = mergeFunction;
    }

    @Override
    public Supplier<Map<K, V>> supplier() {
        return HashMap::new;
    }

    @Override
    public BiConsumer<Map<K, V>, T> accumulator() {
        return (map, element) -> {
            K key = keyMapper.apply(element);
            V value = valueMapper.apply(element);
            map.merge(key, value, mergeFunction);
        };
    }

    @Override
    public BinaryOperator<Map<K, V>> combiner() {
        return (map1, map2) -> {
            map2.forEach((key, value) -> map1.merge(key, value, mergeFunction));
            return map1;
        };
    }

    @Override
    publicFunction<Map<K, V>, Map<K, V>> finisher() {
        returnFunction.identity();
    }

    @Override
    public Set<Characteristics> characteristics() {
        return Collections.unmodifiableSet(EnumSet.of(Characteristics.IDENTITY_FINISH));
    }
}

這個自定義收集器可以將流中的元素收集到一個 Map 中,支持自定義鍵映射、值映射和合并策略。使用時,可以像這樣調用:

Map<Long, String> userMap = users.stream()
    .collect(new CustomCollector<>(User::getId, User::getName, (oldValue, newValue) -> oldValue));

這樣,就可以避免使用 toMap () 時的重復鍵和 null 值問題,同時保持代碼的靈活性和可讀性。

三、實戰案例:toMap () 的 “坑” 與 “避坑指南”

1. 案例一:用戶行為分析

(1)需求描述

某電商平臺需要分析用戶的購買行為,統計每個用戶的購買次數和總金額。要求將結果存儲到一個 Map 中,其中鍵是用戶 id,值是一個包含購買次數和總金額的對象。

(2)使用 toMap () 的實現

List<Order> orders = ...;
Map<Long, PurchaseStats> purchaseStatsMap = orders.stream()
    .collect(Collectors.toMap(
        Order::getUserId,
        order -> new PurchaseStats(1, order.getAmount()),
        (oldStats, newStats) -> new PurchaseStats(
            oldStats.getCount() + newStats.getCount(),
            oldStats.getTotalAmount() + newStats.getTotalAmount()
        )
    ));

這段代碼使用 toMap () 的三參數重載方法,自定義了合并策略,將每個用戶的購買次數和總金額進行累加。

(3)問題分析

  • 重復鍵處理:如果同一個用戶有多個訂單,合并策略會正確累加購買次數和總金額。
  • null 值處理:如果某個訂單的用戶 id 為 null,會拋出NullPointerException。
  • 性能問題:如果訂單量很大,并行流可能會導致性能問題。

(4)優化方案

  • 過濾 null 用戶 id:
Map<Long, PurchaseStats> purchaseStatsMap = orders.stream()
    .filter(order -> order.getUserId() != null)
    .collect(Collectors.toMap(
        Order::getUserId,
        order -> new PurchaseStats(1, order.getAmount()),
        (oldStats, newStats) -> new PurchaseStats(
            oldStats.getCount() + newStats.getCount(),
            oldStats.getTotalAmount() + newStats.getTotalAmount()
        )
    ));
  • 使用并行流和 toConcurrentMap ():
Map<Long, PurchaseStats> purchaseStatsMap = orders.parallelStream()
    .filter(order -> order.getUserId() != null)
    .collect(Collectors.toConcurrentMap(
        Order::getUserId,
        order -> new PurchaseStats(1, order.getAmount()),
        (oldStats, newStats) -> new PurchaseStats(
            oldStats.getCount() + newStats.getCount(),
            oldStats.getTotalAmount() + newStats.getTotalAmount()
        )
    ));

這樣,可以提高處理效率,同時避免線程安全問題。

2. 案例二:日志分析

(1)需求描述

某系統需要分析日志數據,統計每個日志級別(如 INFO、WARN、ERROR)的日志數量,并將結果存儲到一個 Map 中,其中鍵是日志級別,值是日志數量。

(2)使用 groupingBy 的實現

List<Log> logs = ...;
Map<String, Long> logCountMap = logs.stream()
    .collect(Collectors.groupingBy(
        Log::getLevel,
        Collectors.counting()
    ));

這段代碼使用 groupingBy () 和 counting () 收集器,簡單高效地統計了每個日志級別的日志數量。

(3)問題分析

  • 無需處理重復鍵:因為日志級別是唯一的,所以不會出現重復鍵的問題。
  • 性能問題:如果日志量很大,并行流可以提高處理效率。

(4)優化方案

Map<String, Long> logCountMap = logs.parallelStream()
    .collect(Collectors.groupingByConcurrent(
        Log::getLevel,
        Collectors.counting()
    ));

使用groupingByConcurrent()可以在并行流中高效地進行分組統計,提高處理效率。

四、總結:toMap () 的正確打開方式

1. 什么時候可以用 toMap ()?

  • 數據明確唯一:當你確定流中的元素不會產生重復鍵時,可以使用 toMap ()。
  • 簡單映射需求:當你只需要將元素映射到 Map 中,不需要復雜的合并策略或統計聚合時,可以使用 toMap ()。
  • 非并行處理:當你不需要使用并行流時,可以使用 toMap ()。

2. 什么時候應該避免使用 toMap ()?

  • 可能存在重復鍵:如果流中的元素可能產生重復鍵,應該使用三參數的 toMap () 或其他替代方法。
  • 需要處理 null 值:如果鍵或值可能為 null,應該在流處理過程中進行過濾或提供默認值。
  • 并行處理需求:如果需要使用并行流,應該使用 toConcurrentMap () 或其他支持并發的收集器。

3. 替代方案推薦

  • 分組處理:使用 groupingBy () 進行分組統計,避免重復鍵和 null 值問題。
  • 自定義收集器:當內置收集器無法滿足需求時,使用自定義收集器實現靈活的收集邏輯。
  • 并行處理:使用 toConcurrentMap () 或 groupingByConcurrent () 在并行流中進行高效處理。

4. 最后的忠告

toMap () 是一個強大的工具,但也是一個危險的工具。它的簡單易用性可能會掩蓋潛在的問題,導致代碼在生產環境中出現意想不到的錯誤。因此,在使用 toMap () 時,一定要謹慎處理重復鍵、null 值和性能問題,或者選擇更合適的替代方案。

責任編輯:武曉燕 來源: 石杉的架構筆記
相關推薦

2024-07-10 10:15:43

2024-11-05 10:24:50

2022-03-26 08:49:13

MySQL數據存儲

2018-02-06 08:42:10

永久內存XPoint閃存

2021-01-29 11:05:50

PrintPython代碼

2016-06-12 09:48:40

2017-08-31 17:00:20

2016-05-03 09:48:58

2023-11-29 08:19:45

Go泛型缺陷

2020-09-08 08:45:39

jupyter插件代碼

2025-10-20 04:00:00

2021-09-10 08:00:00

Python機器學習開發

2021-03-17 16:53:51

IO多路

2017-12-07 11:27:30

編程開發代碼

2023-10-31 08:01:48

Mybatis參數jdbcurl?

2018-04-10 13:40:14

Kubernetes容器服務器

2025-08-22 10:28:33

RSTP無線冗余網絡

2025-04-09 03:00:00

簽字板代碼canvas

2021-02-07 10:17:22

項目架構技術管理

2021-04-07 20:01:23

Go變量常量
點贊
收藏

51CTO技術棧公眾號

日韩av片在线免费观看| 黄网站欧美内射| 国产精品探花视频| 好看的av在线不卡观看| 亚洲国产小视频| 欧美三级午夜理伦三级| 麻豆网站在线观看| 成人午夜av电影| 国产成人免费91av在线| 国产盗摄一区二区三区在线| 日韩啪啪网站| 欧美一区二区三区白人| 丰满少妇久久久| 免费超碰在线| 久久久久久久久久电影| 91久久久久久久一区二区| 国产一级视频在线| 狠狠综合久久av一区二区蜜桃| 欧美一区二区免费视频| 日本一极黄色片| 女囚岛在线观看| 国产女人18毛片水真多成人如厕 | 国产伦精品一区二区三区免费迷| 高清一区二区三区日本久| 青娱乐国产视频| 国产精品2023| 欧美一区三区二区| 青青草精品视频在线观看| 26uuu亚洲电影在线观看| 久久久精品一品道一区| 国产精品伊人日日| 99热这里只有精品在线观看| 葵司免费一区二区三区四区五区| 欧美精品午夜视频| 午夜精品久久久久99蜜桃最新版| 日韩av午夜| 亚洲成人久久久| 337p日本欧洲亚洲大胆张筱雨 | 久草中文在线观看| 国产亚洲精品7777| 精品视频高清无人区区二区三区| 国产精品系列视频| 美女视频第一区二区三区免费观看网站| 91成人免费观看网站| 久久久久久久久久久久久久免费看 | 欧美爱爱视频| 色天使久久综合网天天| 男人用嘴添女人下身免费视频| 91麻豆免费在线视频| 亚洲同性同志一二三专区| 亚洲国产一区在线| av网站大全在线观看| 久久久亚洲精品石原莉奈| 狼狼综合久久久久综合网| 天堂v在线观看| av电影在线观看不卡| 国产高清一区视频| 亚洲国产成人在线观看| 国产成人99久久亚洲综合精品| 91免费国产视频| 国产欧美一区二区三区视频在线观看| 久久av中文字幕片| 91免费看国产| 草草视频在线播放| 99久久婷婷国产精品综合| 精品一区二区三区免费毛片| 天天操天天射天天舔| 99久久婷婷国产综合精品| 另类欧美小说| 亚洲免费视频一区二区三区| 国产女同性恋一区二区| 宅男av一区二区三区| 精产国品自在线www| 一区2区3区在线看| 夜夜添无码一区二区三区| 国产欧美一区二区三区精品酒店| 91久久一区二区| 中文字幕久久av| 亚洲乱码一区| 日韩激情视频在线播放| 四虎成人免费影院| 欧美福利影院| 91精品国产电影| 中文字幕av片| 国产不卡视频在线观看| 精品免费一区二区三区蜜桃| 成年人在线观看网站| 亚洲色欲色欲www| 少妇人妻无码专区视频| 岛国精品在线| 精品国产乱子伦一区| 男人操女人动态图| 91精品一区二区三区综合| 午夜精品久久久久久99热| 国产情侣小视频| 国产成人av电影| 视频三区二区一区| a级片免费在线观看| 在线欧美一区二区| 国产精品91av| 精品日本12videosex| 欧美成人精品在线| 国产一卡二卡三卡| 高清在线不卡av| 亚洲一区二区在| 忘忧草在线日韩www影院| 欧美日本视频在线| 美国黄色一级毛片| 欧美精品入口| 国产精品亚洲视频在线观看| 秋霞视频一区二区| 亚洲日本在线天堂| 激情内射人妻1区2区3区| 91蝌蚪精品视频| 中文字幕亚洲天堂| 丰满少妇乱子伦精品看片| 国内精品视频一区二区三区八戒| 玛丽玛丽电影原版免费观看1977| av理论在线观看| 欧美私人免费视频| 美女久久久久久久久久| 亚洲日本免费| 亚洲综合自拍一区| 婷婷激情在线| 91久久线看在观草草青青| 怡红院一区二区| 欧美激情1区2区| 国产一区二区丝袜| 大胆av不用播放器在线播放| 欧美日韩国产精品一区二区不卡中文 | 日本福利一区二区三区| 国产精品yjizz视频网| 欧美一区二区福利在线| 男人av资源站| 久久国产精品99久久人人澡| 日韩视频在线播放| 88xx成人永久免费观看| 日韩av网站在线| 久久精品国产亚洲av香蕉| 国产经典欧美精品| 2021国产视频| **爰片久久毛片| 欧美美女操人视频| 亚洲AV无码精品色毛片浪潮| 亚洲视频在线一区二区| 亚洲免费成人在线视频| 欧美激情偷拍自拍| 成人激情免费在线| 日本中文字幕在线2020| 欧美日韩一区二区三区四区五区| 小早川怜子久久精品中文字幕| 噜噜噜在线观看免费视频日韩| 欧美二区在线看| 日韩网站中文字幕| 日韩综合中文字幕| 国产男男gay网站| 亚洲美女偷拍久久| 日本女人性视频| 亚洲黄色三级| 麻豆成人av| 亚洲第一会所| xxx一区二区| av综合在线观看| 亚洲va韩国va欧美va精品| 黄色网址在线视频| 水蜜桃久久夜色精品一区的特点| 天堂一区二区三区| 国产999精品在线观看| 久久99精品久久久久久琪琪| 人妻一区二区三区免费| 日韩欧美黄色动漫| 国产精品综合激情| 国产精品夜夜爽| 5月婷婷6月丁香| 欧美日韩中文字幕一区二区三区| 国产欧美在线播放| 黄色成人在线网| 亚洲免费伊人电影在线观看av| 黄色av网站免费| 亚洲视频在线一区二区| 强迫凌虐淫辱の牝奴在线观看| 葵司免费一区二区三区四区五区| 一区二区三区四区久久| 久久中文资源| 国产欧美精品一区二区三区介绍| 人人澡人人添人人爽一区二区| 日韩国产精品一区| 亚洲最新av网站| 性感美女久久精品| 无码人中文字幕| 成人中文字幕电影| 无码内射中文字幕岛国片| 最新欧美人z0oozo0| 欧美日韩一区综合| 视频一区在线| 国产精品第一页在线| 欧美黄色视屏| 在线精品视频视频中文字幕| 亚洲精品久久久久久久久久久久久久| 色综合亚洲欧洲| 久草网站在线观看| 中文字幕乱码一区二区免费| 国模无码视频一区| 国内精品写真在线观看| 欧美一级黄色影院| 亚洲看片一区| 国产手机视频在线观看| 国内精品久久久久久99蜜桃| 国产精品 日韩| 日韩三区四区| 国产97色在线|日韩| 青青在线视频| 久久精彩免费视频| www免费网站在线观看| 亚洲韩国青草视频| 亚洲av无码乱码国产精品久久| 91福利国产成人精品照片| 国产无遮挡又黄又爽又色| 亚洲欧美偷拍三级| 欧美激情久久久久久久| 久久综合色婷婷| zjzjzjzjzj亚洲女人| 国产自产2019最新不卡| 天堂社区在线视频| 一本久久综合| 亚洲精品蜜桃久久久久久| 91精品成人| 小说区视频区图片区| 欧美一区二区性| 日韩精品久久久毛片一区二区| 极品尤物一区| 国产欧美欧洲| 国产精品nxnn| 国产精品国产精品| 97视频一区| 国产一级特黄a大片99| 日本亚洲视频| 亚洲精品日韩av| 日本在线一区二区三区| 92看片淫黄大片看国产片| 亚洲色图综合| 成人自拍性视频| 国产精品视频一区二区三区| 成人精品久久一区二区三区| 亚洲一区二区小说| 成人一区二区电影| 日本久久伊人| 国产一区免费在线| 女仆av观看一区| 九九九久久久| 国产精品手机在线播放| 日韩欧美亚洲在线| 日韩精品四区| 色乱码一区二区三区熟女| 91av精品| 国产手机免费视频| 国产农村妇女精品一二区| 国产一区二区三区精彩视频| 久久精品三级| 日韩欧美国产片| 国产中文字幕精品| 亚洲熟女一区二区三区| 99精品热视频| 精品一区二区三区蜜桃在线| 国产精品视频yy9299一区| 国产suv精品一区二区68| 亚洲精品视频在线观看免费| 日本熟妇乱子伦xxxx| 福利一区福利二区微拍刺激| 日本在线播放视频| 欧美性猛片xxxx免费看久爱| 国产男女裸体做爰爽爽| 亚洲精品国产福利| 超碰免费在线| 欧美大片在线看| 亚洲黄色网址| 成人免费看片视频| 老司机成人在线| 先锋影音网一区| 国产精品啊啊啊| 岳毛多又紧做起爽| 国产一区在线不卡| 国产精品无码电影| 国产精品九色蝌蚪自拍| 精品无码人妻一区二区三区品| 精品久久久免费| 亚洲无码久久久久| 精品国产制服丝袜高跟| 国产色a在线| 欧美日韩成人精品| 欧美va在线观看| 国产欧美欧洲| 久久精品青草| 久久国产乱子伦免费精品| 国产综合久久久久影院| 国产人妻一区二区| 亚洲日本电影在线| 久久久久久久久久久久久久av| 欧美日韩在线播放| 深夜福利免费在线观看| 久久999免费视频| 久久日本片精品aaaaa国产| 国产精品福利视频| 999成人网| 欧美日韩第二页| 成人性视频免费网站| 久草福利资源在线| 色婷婷综合久久| 内射后入在线观看一区| 久久精品国产电影| 制服诱惑亚洲| 国内精品国语自产拍在线观看| 欧美hentaied在线观看| 欧洲av无码放荡人妇网站| 国产成人精品一区二区三区四区 | 国产精品99久久久久久www| 超碰成人97| 看一级黄色录像| 麻豆成人综合网| 成人黄色免费网址| 精品久久久久久国产| 亚洲AV无码精品色毛片浪潮| 久久亚洲欧美日韩精品专区| 福利视频一区| 日本一区网站| 久久精品123| 中文字幕在线观看的网站| 亚洲国产精品一区二区久久恐怖片| 国产一区二区三区成人| 色综合影院在线| 国产极品嫩模在线观看91精品| 欧美性色黄大片人与善| 午夜在线精品| 插吧插吧综合网| 懂色av影视一区二区三区| 男人天堂一区二区| 国产最新精品视频| 黄色欧美在线| 亚欧无线一线二线三线区别| hitomi一区二区三区精品| 国产精品suv一区二区| 精品国产免费视频| 超碰在线最新网址| 国内不卡一区二区三区| 亚洲一区黄色| 亚欧洲乱码视频| 欧洲人成人精品| 一区二区三区视频在线观看视频| 国产精品免费久久久| 日韩久久精品网| 超碰人人草人人| 综合在线观看色| 国产免费黄色大片| 久久久这里只有精品视频| 精品欧美午夜寂寞影院| 男人添女人下面高潮视频| 91蜜桃免费观看视频| 日本视频免费观看| 伊人久久综合97精品| 福利一区在线| 日本一本草久p| 99久久精品免费看国产| 五月婷婷亚洲综合| 伊人久久久久久久久久| 韩国三级成人在线| 久久久久久免费看| 久久精品亚洲精品国产欧美kt∨ | 亚洲人成在线网站| 视频一区二区在线| 国产一区二区三区久久久| 久久久国产精品黄毛片| 日韩av中文字幕在线播放| 成人免费网站www网站高清| 中文字幕欧美日韩一区二区三区| 国产寡妇亲子伦一区二区| 好吊操这里只有精品| 国产亚洲精品日韩| 国内不卡的一区二区三区中文字幕| 免费在线黄网站| 久久久久久久久久电影| 国产欧美第一页| 日韩免费高清在线观看| 中出一区二区| 性久久久久久久久久| 制服丝袜亚洲播放| 欲香欲色天天天综合和网| 国产福利片一区二区| www.久久精品| 国产精品久久久午夜夜伦鲁鲁| 久久久久久中文字幕| 欧美亚洲激情| 亚洲天堂美女视频| 欧美三电影在线| 玖玖在线播放| 国产午夜精品视频一区二区三区| 26uuu国产一区二区三区| 国产三区在线播放| 国产精品成人久久久久| 亚洲东热激情| 最新一区二区三区|