精品欧美一区二区三区在线观看 _久久久久国色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毛片| 热re91久久精品国99热蜜臀| 久久久久久三级| 99视频在线观看地址| 国产在线麻豆精品观看| 久久久久久久久久婷婷| 一区二区三区四区免费| 亚洲网站免费| 精品久久久久久久久久久久久久| 2020国产精品久久精品不卡| 久久久久久久黄色片| 成人在线丰满少妇av| 日韩亚洲欧美在线| 日韩欧美亚洲天堂| 国产成人在线视频免费观看| 波多野洁衣一区| 欧美精品xxx| 国产精品色悠悠| 国产a级片网站| 成年网站在线| 成人看片黄a免费看在线| 国产精品久久久久久久9999| 国产一级二级三级| 成人写真视频| 精品视频在线播放色网色视频| 成人毛片一区二区| 日本欧美在线视频免费观看| 粉嫩一区二区三区性色av| 国产精品成人国产乱一区| 国产又黄又粗的视频| 国产一区在线电影| 欧美成人欧美edvon| www.夜夜爽| 成人在线爆射| 香港成人在线视频| 欧美一级二级三级| 人妻夜夜爽天天爽| 成人免费高清视频在线观看| 91免费看片网站| 一级特黄色大片| 日韩不卡一区二区三区| 欧美中文在线视频| 一本在线免费视频| 精品国产网站| 日韩国产激情在线| 国产精品久久久免费观看| 日本少妇一区| 色婷婷av久久久久久久| 一区二区传媒有限公司| 超黄网站在线观看| 亚洲一区二区三区免费视频| 国产免费xxx| 黄网页免费在线观看| 亚洲国产电影在线观看| 日韩一区二区电影在线观看| 国产乱视频在线观看| 国产精品一区不卡| 99se婷婷在线视频观看| 国产99对白在线播放| 国产精品夜夜嗨| 97自拍视频| 丰满肉肉bbwwbbww| 日本美女高清在线观看免费| 精品一区在线看| 国产在线精品播放| 国产精品久久久久久久一区二区 | 欧美日韩大陆在线| 国产视频手机在线播放| jizz久久久久久| 欧美日韩二区三区| 无码人妻aⅴ一区二区三区玉蒲团| 免费看av不卡| 在线观看日韩毛片| av中文字幕网址| 另类专区亚洲| 精品视频一区二区三区免费| 久久精品亚洲天堂| 亚洲一区二区三区免费| 日韩av综合网| 免费看日本黄色片| 2023国产精品久久久精品双| 欧美黑人又粗大| 69视频免费在线观看| 久久精品五月| 91精品综合视频| 亚洲欧美另类一区| 91老司机福利 在线| 成人在线观看av| 香蕉视频免费看| 成人免费视频视频在线观看免费| 91精品视频免费看| 蜜桃久久一区二区三区| 久久精品夜色噜噜亚洲aⅴ| 国产在线观看一区| xxxxx日韩| 亚洲在线视频一区| 国产性生交xxxxx免费| 国产一精品一av一免费爽爽| 日韩av在线网址| 日本黄色免费片| 亚洲伦伦在线| 成人免费观看a| 日韩在线免费看| 久久综合久久综合久久综合| 久久综合给合久久狠狠色| 日本不卡在线| 狠狠色香婷婷久久亚洲精品| 亚洲国产成人精品电影| 三级性生活视频| 日韩欧美ww| 久久国产天堂福利天堂| 丁香社区五月天| 高清av一区二区| 国产超碰91| 日韩一级片免费在线观看| 国产xxx精品视频大全| 美女亚洲精品| 黄网站在线观| 欧美精品丝袜中出| 在线观看一区二区三区视频| 国产探花在线精品| 亚州国产精品久久久| 国产男女猛烈无遮挡| 国产成人午夜精品影院观看视频 | 成人性做爰aaa片免费看不忠| 中文字幕在线高清| 日韩欧美国产一二三区| 在线看片中文字幕| 午夜一区不卡| 久久成人资源| 888av在线视频| 日韩欧美一级特黄在线播放| 天天摸日日摸狠狠添| 久久久久欧美精品| 狠狠爱一区二区三区| 欧美亚洲系列| 欧美一区二区在线免费播放| 日本黄色录像视频| 麻豆国产精品官网| 视频一区国产精品| 韩日精品一区| 国产一区二区三区视频| 久久精品无码av| 2017欧美狠狠色| 一区二区三区四区视频在线观看| 毛片网站在线看| 日韩精品一区二区三区中文精品| 麻豆国产精品一区| 日韩视频二区| 精品国产一区二区三| √8天堂资源地址中文在线| 热久久久久久久| 亚洲欧美国产另类| 日本一级淫片免费放| www.欧美日韩| 男人日女人逼逼| 欧美理伦片在线播放| 91av国产在线| 九一国产在线| 亚洲色图制服诱惑| 黄色片子免费看| 精品国产乱码| 国产精自产拍久久久久久| jizz在线观看中文| 欧美日韩国产限制| 日韩在线免费观看av| 日韩国产一区二| 精品国产第一页| 一区二区精品伦理...| 亚洲欧美中文日韩在线| 中文字幕人妻丝袜乱一区三区| 成人综合在线观看| 天堂…中文在线最新版在线| 美女久久99| 国产精品久久久久久久久久久久| 无码国产伦一区二区三区视频| 亚洲人成在线观看一区二区| 久久久久久国产精品日本| 日韩中字在线| 99re视频在线播放| 中文在线а√在线8| 正在播放欧美一区| www天堂在线| 精品福利免费观看| 色哟哟视频在线| 视频一区视频二区在线观看| 一区不卡字幕| 久久日本片精品aaaaa国产| 日韩视频―中文字幕| 国产乡下妇女三片| 亚洲精品综合在线| 成人网站免费观看| 紧缚捆绑精品一区二区| 国产 日韩 亚洲 欧美| 操欧美女人视频| 国产精品99久久久久久人 | 青青草91视频| 国产日韩欧美大片| 日本成人手机在线| 97视频在线观看免费高清完整版在线观看 | 少妇视频一区二区| 久久久久欧美精品| 中文字幕の友人北条麻妃| 外国成人在线视频| 亚洲一区二区三区毛片| 成人av免费| 国产视频精品va久久久久久| 国产女人高潮毛片| 在线视频中文字幕一区二区| 青青草自拍偷拍| 成人黄色在线视频| 91亚洲免费视频| 婷婷综合五月| 欧洲精品在线一区| jizz性欧美23| 成人有码视频在线播放| 欧美成人精品一区二区男人小说| 亚洲网站在线观看| 亚洲国产精彩视频| 姬川优奈aav一区二区| 精品人妻伦九区久久aaa片| 国产精品99久久久久久久vr| 欧美精品成人网| 在线一区欧美| 日韩视频在线视频| 尤物tv在线精品| 国产精品成人观看视频免费| 国产精品色婷婷在线观看| 国产激情视频一区| 黄色网在线免费看| 中文欧美在线视频| 麻豆导航在线观看| 亚洲精品自拍偷拍| 天天干天天插天天操| 在线不卡的av| 伊人精品一区二区三区| 色久综合一二码| 亚洲欧美日韩激情| 一本色道久久综合亚洲91| 五月天免费网站| 国产日本亚洲高清| 国产精品久久久久无码av色戒| 久久99久久99小草精品免视看| 亚洲精品久久久久久久蜜桃臀| 综合伊思人在钱三区| 国产欧美一区二区视频| 99久久伊人| 国产精品成熟老女人| 秋霞在线视频| 欧美国产高跟鞋裸体秀xxxhd| 精品亚洲综合| 亚洲人线精品午夜| 高清av电影在线观看| 尤物yw午夜国产精品视频明星| 亚洲男人天堂久久| 久久99精品国产麻豆婷婷 | 中文字幕一区二区久久人妻网站| 久久中文字幕一区二区三区| 日本一本二本在线观看| 亚洲主播在线| 欧在线一二三四区| 精品二区久久| 免费看又黄又无码的网站| 国产欧美在线| 国产综合免费视频| 青青草精品视频| 在线一区二区不卡| 日韩国产高清在线| 国产又大又黄又猛| 国产一区二区三区免费看| 久久久久99人妻一区二区三区| 毛片不卡一区二区| 九色91porny| 99视频在线精品| 韩国女同性做爰三级| 国产精品国产三级国产aⅴ无密码| 少妇户外露出[11p]| 久久久久国产精品麻豆ai换脸| 少妇被狂c下部羞羞漫画| 黑人巨大精品欧美一区| 一区二区三区四区影院| xfplay精品久久| 香蕉久久久久久久| 夜夜嗨av一区二区三区网页| 欧美肥妇bbwbbw| 亚洲综合男人的天堂| 全网免费在线播放视频入口| 中文字幕一区二区5566日韩| 精品97人妻无码中文永久在线 | 国产一级片久久| 欧美天天综合色影久久精品| 中文字幕永久在线观看| 欧美成人精品福利| 国产特黄在线| 欧美黄色性视频| yw.尤物在线精品视频| 亚洲在线视频观看| 亚洲人成伊人成综合图片| 久久国产欧美精品| 久久精品国产大片免费观看| 99色这里只有精品| 另类中文字幕网| 亚洲av成人精品一区二区三区 | 美日韩一区二区| 91传媒理伦片在线观看| 99这里只有久久精品视频| 中国特黄一级片| 欧美日韩在线观看视频| 国产精品无码久久久久成人app| 欧美电影一区二区| 天堂а在线中文在线无限看推荐| 亚洲精品综合久久中文字幕| 992kp免费看片| 国产精品老牛| 国产成人av免费观看| 国产精品国产a| 国产免费一级视频| 亚洲国产精品人人爽夜夜爽| 黄色精品免费看| 欧美裸体男粗大视频在线观看| 午夜羞羞小视频在线观看| 欧美极品欧美精品欧美视频 | 一区二区三区色| 国产精品成人无码| 欧美一区二区三区在线视频| 美州a亚洲一视本频v色道| 中文字幕欧美日韩精品| 中文字幕人成乱码在线观看| 国产精品乱码一区二区三区| 你懂的网址国产 欧美| 日本美女视频一区| 国产精品美女久久久久高潮| 欧美日韩中文字幕在线观看| 激情久久av一区av二区av三区| 超碰在线免费97| 亚洲美女在线看| 黄色免费在线网站| 国产精品精品一区二区三区午夜版| 亚洲欧美在线人成swag| 国产乱码精品一区二区三区中文 | www.欧美精品一二三区| 搜成人激情视频| 欧洲精品亚洲精品| 丝袜美腿一区二区三区| 精品成人av一区二区三区| 狠狠久久五月精品中文字幕| 亚洲 另类 春色 国产| 91国在线精品国内播放| 日韩美女国产精品| 欧美激情国产精品日韩| 国产乱子轮精品视频| 91香蕉视频在线播放| 欧美一区二区成人6969| 亚洲小说区图片区都市| 亚洲自拍偷拍区| 俺要去色综合狠狠| 久久久久久免费看| 九色综合狠狠综合久久| 中文字幕丰满孑伦无码专区| 一区二区在线观看av| 国产三级午夜理伦三级| 欧美另类高清videos| h1515四虎成人| 久久久久久久久一区| 久久免费高清| 激情无码人妻又粗又大| 色菇凉天天综合网| 黄色aaa毛片| 69久久夜色精品国产7777| 国产va免费精品观看精品视频 | 亚洲一区日韩在线| 国产成人av一区二区三区不卡| 亚洲一区在线视频观看| 日本xxxxwww| 国产成人精品电影久久久| 成人在线国产| 三上悠亚 电影| 日韩欧美成人区| 日本中文字幕在线视频| 2022国产精品| 综合一区av| www.久久av.com| 国产精品欧美极品| 亚洲AV无码一区二区三区少妇| 久久久精品一区| 国产精品45p| 手机看片福利日韩| 国产丝袜欧美中文另类| 在线精品免费视| 亚洲毛片一区二区| 日韩国产大片| 自拍日韩亚洲一区在线| 国产精品美女久久久久久2018| 中文字幕在线观看国产| 中文字幕不卡在线视频极品| 欧美国产中文高清| 成年人网站大全| 亚洲影视资源网| 成人h小游戏| 精品视频免费观看|