最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java 集合框架高級應(yīng)用與架構(gòu)設(shè)計方案

 更新時間:2026年02月11日 11:18:36   作者:星河耀銀海  
文章主要介紹了Java集合框架在復雜架構(gòu)場景中的高級應(yīng)用,包括緩存設(shè)計、分層存儲、數(shù)據(jù)分片、設(shè)計模式融合實踐、大數(shù)據(jù)量處理以及分布式場景中集合的適配問題和優(yōu)化方案,感興趣的朋友跟隨小編一起看看吧

一、章節(jié)學習目標與重點

1.1 學習目標

  • 掌握集合框架在復雜架構(gòu)場景中的高級應(yīng)用(緩存設(shè)計、分層存儲、數(shù)據(jù)分片)
  • 理解集合與設(shè)計模式的結(jié)合實踐(享元模式、裝飾器模式、迭代器模式等)
  • 精通高并發(fā)、大數(shù)據(jù)量場景下集合的架構(gòu)優(yōu)化方案
  • 解決集合在分布式、微服務(wù)架構(gòu)中的適配問題
  • 能夠基于集合框架設(shè)計可擴展、高性能的核心業(yè)務(wù)組件

1.2 學習重點

  • 基于集合的緩存架構(gòu)設(shè)計(本地緩存、多級緩存)
  • 集合與設(shè)計模式的深度融合實踐
  • 大數(shù)據(jù)量下集合的分片存儲與并行處理架構(gòu)
  • 分布式場景中集合的數(shù)據(jù)一致性與傳輸優(yōu)化
  • 集合框架驅(qū)動的業(yè)務(wù)組件設(shè)計(配置中心、規(guī)則引擎)

二、基于集合的緩存架構(gòu)設(shè)計實戰(zhàn)

?? 緩存是提升系統(tǒng)性能的核心手段,而 Java 集合框架是實現(xiàn)本地緩存的基礎(chǔ)?;诩系木彺嬖O(shè)計需兼顧查詢效率、內(nèi)存占用、過期策略、線程安全四大核心訴求,常用集合包括 HashMap、LinkedHashMap、WeakHashMap 等。

2.1 本地緩存設(shè)計核心要素

  • 存儲結(jié)構(gòu):選擇合適的集合實現(xiàn)類(如 HashMap 用于高效查詢,LinkedHashMap 用于 LRU 過期策略)
  • 過期策略:支持時間過期(TTL)、空間淘汰(LRU/LFU)
  • 線程安全:高并發(fā)場景需保證讀寫安全
  • 內(nèi)存控制:避免緩存膨脹,支持自動回收無用數(shù)據(jù)

2.2 基于 LinkedHashMap 的 LRU 緩存實現(xiàn)(固定容量+TTL)

LinkedHashMap 天然支持訪問順序維護,結(jié)合 removeEldestEntry() 方法可實現(xiàn) LRU 淘汰,擴展后支持 TTL 過期策略:

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.locks.ReentrantLock;
/**
 * 基于 LinkedHashMap 的 LRU+TTL 本地緩存
 * 特性:固定容量(LRU 淘汰)、時間過期(TTL)、線程安全
 */
public class LruTtlCache<K, V> extends LinkedHashMap<K, CacheEntry<V>> {
    private final int maxCapacity; // 最大容量
    private final long ttlMillis; // 過期時間(毫秒)
    private final ReentrantLock lock = new ReentrantLock(); // 可重入鎖保證線程安全
    // 緩存條目:包裝值和過期時間
    private static class CacheEntry<V> {
        V value;
        long expireTime; // 過期時間戳(毫秒)
        CacheEntry(V value, long expireTime) {
            this.value = value;
            this.expireTime = expireTime;
        }
        // 判斷是否過期
        boolean isExpired() {
            return System.currentTimeMillis() > expireTime;
        }
    }
    // 構(gòu)造函數(shù):指定最大容量和 TTL
    public LruTtlCache(int maxCapacity, long ttlMillis) {
        super(maxCapacity, 0.75f, true); // accessOrder=true(訪問順序)
        this.maxCapacity = maxCapacity;
        this.ttlMillis = ttlMillis;
    }
    /**
     * 重寫 removeEldestEntry:達到最大容量時刪除最久未使用的條目
     */
    @Override
    protected boolean removeEldestEntry(Map.Entry<K, CacheEntry<V>> eldest) {
        // 先清理過期條目
        if (eldest.getValue().isExpired()) {
            return true;
        }
        // 未過期則判斷是否超容量
        return size() > maxCapacity;
    }
    /**
     * 存緩存:線程安全
     */
    public void put(K key, V value) {
        Objects.requireNonNull(key);
        Objects.requireNonNull(value);
        lock.lock();
        try {
            // 計算過期時間戳
            long expireTime = System.currentTimeMillis() + ttlMillis;
            super.put(key, new CacheEntry<>(value, expireTime));
        } finally {
            lock.unlock();
        }
    }
    /**
     * 取緩存:線程安全,自動過濾過期條目
     */
    public V get(Object key) {
        lock.lock();
        try {
            CacheEntry<V> entry = super.get(key);
            if (entry == null) {
                return null;
            }
            // 過期則刪除并返回 null
            if (entry.isExpired()) {
                super.remove(key);
                return null;
            }
            return entry.value;
        } finally {
            lock.unlock();
        }
    }
    /**
     * 批量清理過期條目
     */
    public void cleanExpired() {
        lock.lock();
        try {
            keySet().removeIf(key -> super.get(key).isExpired());
        } finally {
            lock.unlock();
        }
    }
}

2.3 多級緩存架構(gòu)設(shè)計(本地緩存+分布式緩存)

在微服務(wù)架構(gòu)中,單一本地緩存無法滿足分布式部署需求,需設(shè)計“本地緩存+分布式緩存”的多級架構(gòu):

2.3.1 架構(gòu)示意圖

應(yīng)用服務(wù) A                應(yīng)用服務(wù) B
┌───────────────┐        ┌───────────────┐
│ 本地緩存      │        │ 本地緩存      │
│ (LruTtlCache)│        │ (LruTtlCache)│
└───────┬───────┘        └───────┬───────┘
        │                        │
        └───────────┬───────────┘
                    │
            ┌───────▼───────┐
            │ 分布式緩存    │
            │ (Redis)     │
            └───────┬───────┘
                    │
            ┌───────▼───────┐
            │ 數(shù)據(jù)庫        │
            └───────────────┘

2.3.2 核心邏輯

  1. 讀取數(shù)據(jù):優(yōu)先查本地緩存 → 本地未命中查分布式緩存 → 分布式未命中查數(shù)據(jù)庫,查詢結(jié)果回寫兩級緩存
  2. 更新數(shù)據(jù):更新數(shù)據(jù)庫 → 淘汰分布式緩存 → 淘汰所有應(yīng)用節(jié)點的本地緩存(通過消息通知)
  3. 優(yōu)勢:本地緩存提升響應(yīng)速度,分布式緩存保證分布式一致性,數(shù)據(jù)庫保證數(shù)據(jù)持久化

2.3.3 代碼簡化實現(xiàn)(多級緩存客戶端)

import redis.clients.jedis.Jedis;
import java.util.function.Supplier;
/**
 * 多級緩存客戶端(本地緩存+Redis)
 */
public class MultiLevelCache<K, V> {
    private final LruTtlCache<K, V> localCache;
    private final Jedis redisClient;
    private final String prefix; // Redis 鍵前綴
    private final long redisTtlSeconds; // Redis 過期時間(秒)
    // 構(gòu)造函數(shù):初始化各級緩存
    public MultiLevelCache(int localMaxCapacity, long localTtlMillis,
                          Jedis redisClient, String prefix, long redisTtlSeconds) {
        this.localCache = new LruTtlCache<>(localMaxCapacity, localTtlMillis);
        this.redisClient = redisClient;
        this.prefix = prefix;
        this.redisTtlSeconds = redisTtlSeconds;
    }
    /**
     * 讀取緩存:自動降級查詢
     * @param key 緩存鍵
     * @param loader 數(shù)據(jù)庫加載器(緩存未命中時執(zhí)行)
     * @return 緩存值
     */
    public V get(K key, Supplier<V> loader) {
        // 1. 查本地緩存
        V value = localCache.get(key);
        if (value != null) {
            return value;
        }
        // 2. 查 Redis 緩存
        String redisKey = prefix + key;
        String redisValue = redisClient.get(redisKey);
        if (redisValue != null) {
            V deserialized = deserialize(redisValue); // 反序列化
            localCache.put(key, deserialized); // 回寫本地緩存
            return deserialized;
        }
        // 3. 查數(shù)據(jù)庫并回寫緩存
        value = loader.get();
        if (value != null) {
            localCache.put(key, value);
            redisClient.setex(redisKey, redisTtlSeconds, serialize(value)); // 序列化并設(shè)置過期時間
        }
        return value;
    }
    /**
     * 淘汰緩存:更新數(shù)據(jù)時調(diào)用
     */
    public void evict(K key) {
        localCache.remove(key); // 淘汰本地緩存
        redisClient.del(prefix + key); // 淘汰 Redis 緩存
        // 發(fā)送消息通知其他節(jié)點淘汰本地緩存(如 RocketMQ/Kafka)
        sendEvictMessage(key);
    }
    // 序列化/反序列化(簡化實現(xiàn),實際可使用 Jackson)
    private String serialize(V value) {
        return value.toString();
    }
    private V deserialize(String value) {
        return (V) value;
    }
    // 發(fā)送緩存淘汰消息(簡化實現(xiàn))
    private void sendEvictMessage(K key) {
        System.out.println("發(fā)送緩存淘汰消息:" + key);
    }
}

2.4 緩存架構(gòu)優(yōu)化要點

  • 本地緩存:使用 LruTtlCache 控制內(nèi)存,定期清理過期數(shù)據(jù),避免內(nèi)存泄漏
  • 分布式緩存:選擇 Redis 等高性能組件,設(shè)置合理 TTL,避免緩存雪崩
  • 一致性保障:更新數(shù)據(jù)時采用“更新數(shù)據(jù)庫→淘汰緩存”順序,結(jié)合消息通知實現(xiàn)分布式緩存一致性
  • 降級策略:分布式緩存不可用時,僅依賴本地緩存+數(shù)據(jù)庫,保證系統(tǒng)可用性

三、集合與設(shè)計模式的深度融合實踐

Java 集合框架本身大量運用設(shè)計模式(如迭代器模式、裝飾器模式),在實際開發(fā)中,結(jié)合設(shè)計模式使用集合可大幅提升代碼的擴展性和可維護性。

3.1 裝飾器模式+集合:增強集合功能

裝飾器模式通過包裝原集合,在不修改原代碼的前提下增強功能(如日志記錄、權(quán)限控制、數(shù)據(jù)校驗)。以下實現(xiàn)一個“帶訪問日志的 List”:

import java.util.*;
/**
 * 裝飾器模式:帶訪問日志的 List
 */
public class LoggingList<E> implements List<E> {
    // 被裝飾的原 List
    private final List<E> target;
    // 日志記錄器(簡化實現(xiàn))
    private final Logger logger = new Logger();
    // 構(gòu)造函數(shù):傳入原 List
    public LoggingList(List<E> target) {
        this.target = Objects.requireNonNull(target);
    }
    /**
     * 增強 add 方法:記錄添加日志
     */
    @Override
    public boolean add(E e) {
        logger.log("添加元素:" + e);
        return target.add(e);
    }
    /**
     * 增強 get 方法:記錄訪問日志
     */
    @Override
    public E get(int index) {
        E e = target.get(index);
        logger.log("訪問索引 " + index + " 的元素:" + e);
        return e;
    }
    /**
     * 其他方法直接委托給原 List(省略重復代碼,實際開發(fā)可通過 IDE 自動生成)
     */
    @Override
    public int size() {
        return target.size();
    }
    @Override
    public boolean isEmpty() {
        return target.isEmpty();
    }
    // ... 其他 List 接口方法(均委托給 target)
    /**
     * 簡化日志類
     */
    private static class Logger {
        public void log(String message) {
            System.out.println("[LoggingList] " + message);
        }
    }
    // 測試
    public static void main(String[] args) {
        List<String> list = new LoggingList<>(new ArrayList<>());
        list.add("Java");
        list.add("集合");
        list.get(0);
        // 輸出:
        // [LoggingList] 添加元素:Java
        // [LoggingList] 添加元素:集合
        // [LoggingList] 訪問索引 0 的元素:Java
    }
}

3.2 享元模式+集合:復用重復對象

享元模式通過緩存重復對象減少內(nèi)存占用,適用于大量相似對象場景(如配置項、常量、商品規(guī)格)。以下基于 HashMap 實現(xiàn)享元池:

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
 * 享元模式:商品規(guī)格享元池(復用重復的規(guī)格對象)
 */
public class SpecificationFlyweightPool {
    // 享元池:緩存規(guī)格對象(key=規(guī)格編碼,value=規(guī)格對象)
    private static final Map<String, Specification> POOL = new HashMap<>();
    /**
     * 獲取規(guī)格對象:存在則復用,不存在則創(chuàng)建并緩存
     */
    public static Specification getSpecification(String color, String size) {
        Objects.requireNonNull(color);
        Objects.requireNonNull(size);
        // 生成唯一編碼(作為享元池 key)
        String key = color + "_" + size;
        // 雙重檢查鎖定(DCL)保證線程安全
        if (!POOL.containsKey(key)) {
            synchronized (SpecificationFlyweightPool.class) {
                if (!POOL.containsKey(key)) {
                    POOL.put(key, new Specification(color, size));
                }
            }
        }
        return POOL.get(key);
    }
    /**
     * 商品規(guī)格類(不可變,確保享元安全復用)
     */
    public static class Specification {
        private final String color;
        private final String size;
        private Specification(String color, String size) {
            this.color = color;
            this.size = size;
        }
        // getter(無 setter,確保不可變)
        public String getColor() {
            return color;
        }
        public String getSize() {
            return size;
        }
        // 重寫 equals 和 hashCode(確保 key 唯一性)
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Specification that = (Specification) o;
            return Objects.equals(color, that.color) && Objects.equals(size, that.size);
        }
        @Override
        public int hashCode() {
            return Objects.hash(color, size);
        }
    }
    // 測試:復用對象
    public static void main(String[] args) {
        Specification spec1 = getSpecification("紅色", "M");
        Specification spec2 = getSpecification("紅色", "M");
        System.out.println(spec1 == spec2); // true(復用同一對象)
    }
}

3.3 迭代器模式+集合:自定義遍歷邏輯

迭代器模式隔離集合的存儲結(jié)構(gòu)與遍歷邏輯,支持自定義遍歷規(guī)則(如過濾、分頁、排序)。以下實現(xiàn)一個“分頁迭代器”:

import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Objects;
/**
 * 迭代器模式:分頁迭代器(按頁遍歷集合)
 */
public class PagingIterator<E> implements Iterator<List<E>> {
    private final List<E> source; // 源集合
    private final int pageSize; // 每頁大小
    private int currentPage; // 當前頁碼(從 0 開始)
    private final int totalPages; // 總頁數(shù)
    /**
     * 構(gòu)造函數(shù):傳入源集合和每頁大小
     */
    public PagingIterator(List<E> source, int pageSize) {
        this.source = Objects.requireNonNull(source);
        if (pageSize <= 0) {
            throw new IllegalArgumentException("每頁大小必須大于 0");
        }
        this.pageSize = pageSize;
        this.currentPage = 0;
        // 計算總頁數(shù)
        this.totalPages = (source.size() + pageSize - 1) / pageSize;
    }
    /**
     * 是否還有下一頁
     */
    @Override
    public boolean hasNext() {
        return currentPage < totalPages;
    }
    /**
     * 獲取下一頁數(shù)據(jù)
     */
    @Override
    public List<E> next() {
        if (!hasNext()) {
            throw new NoSuchElementException("沒有更多頁面");
        }
        // 計算當前頁的起始索引和結(jié)束索引
        int start = currentPage * pageSize;
        int end = Math.min(start + pageSize, source.size());
        List<E> pageData = source.subList(start, end);
        currentPage++;
        return pageData;
    }
    // 測試:分頁遍歷 10 條數(shù)據(jù)(每頁 3 條)
    public static void main(String[] args) {
        List<Integer> list = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        PagingIterator<Integer> iterator = new PagingIterator<>(list, 3);
        int pageNum = 1;
        while (iterator.hasNext()) {
            List<Integer> page = iterator.next();
            System.out.println("第 " + pageNum + " 頁:" + page);
            pageNum++;
        }
        // 輸出:
        // 第 1 頁:[1, 2, 3]
        // 第 2 頁:[4, 5, 6]
        // 第 3 頁:[7, 8, 9]
        // 第 4 頁:[10]
    }
}

四、大數(shù)據(jù)量下集合的分片存儲與并行處理

當數(shù)據(jù)量達到百萬、千萬級別時,單一集合會面臨內(nèi)存溢出、遍歷效率低等問題,需采用“分片存儲+并行處理”架構(gòu),利用多線程和分布式資源提升處理能力。

4.1 集合分片存儲設(shè)計(基于 List 的分片)

將大數(shù)據(jù)量集合拆分為多個小分片(Shard),每個分片存儲部分數(shù)據(jù),便于并行處理和內(nèi)存控制:

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
 * 集合分片工具類:將大 List 拆分為多個小分片
 */
public class ListSharder<T> {
    private final List<T> source; // 源集合
    private final int shardSize; // 每個分片的最大大小
    public ListSharder(List<T> source, int shardSize) {
        this.source = Objects.requireNonNull(source);
        if (shardSize <= 0) {
            throw new IllegalArgumentException("分片大小必須大于 0");
        }
        this.shardSize = shardSize;
    }
    /**
     * 執(zhí)行分片:返回分片列表
     */
    public List<List<T>> shard() {
        List<List<T>> shards = new ArrayList<>();
        int totalSize = source.size();
        if (totalSize == 0) {
            return shards;
        }
        // 計算分片數(shù)量
        int shardCount = (totalSize + shardSize - 1) / shardSize;
        for (int i = 0; i < shardCount; i++) {
            // 計算當前分片的起始和結(jié)束索引
            int start = i * shardSize;
            int end = Math.min(start + shardSize, totalSize);
            // 截取分片并添加到結(jié)果集(ArrayList 是線程不安全的,并行處理時需注意)
            List<T> shard = new ArrayList<>(source.subList(start, end));
            shards.add(shard);
        }
        return shards;
    }
    // 測試:將 100 萬條數(shù)據(jù)拆分為每個分片 1 萬條
    public static void main(String[] args) {
        // 生成 100 萬條測試數(shù)據(jù)
        List<Integer> bigList = new ArrayList<>(1_000_000);
        for (int i = 0; i < 1_000_000; i++) {
            bigList.add(i);
        }
        // 分片(每個分片 10000 條)
        ListSharder<Integer> sharder = new ListSharder<>(bigList, 10_000);
        List<List<Integer>> shards = sharder.shard();
        System.out.println("總數(shù)據(jù)量:" + bigList.size());
        System.out.println("分片數(shù)量:" + shards.size());
        System.out.println("每個分片大小:" + shards.get(0).size());
        // 輸出:
        // 總數(shù)據(jù)量:1000000
        // 分片數(shù)量:100
        // 每個分片大?。?0000
    }
}

4.2 分片并行處理(基于線程池)

將分片分配給線程池并行處理,利用多核 CPU 資源提升處理效率,適用于數(shù)據(jù)篩選、統(tǒng)計、轉(zhuǎn)換等場景:

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
 * 分片并行處理器:基于線程池處理分片數(shù)據(jù)
 */
public class ShardParallelProcessor<T, R> {
    private final ExecutorService executor; // 線程池
    private final int threadCount; // 線程數(shù)(默認 CPU 核心數(shù))
    // 構(gòu)造函數(shù):默認線程數(shù)為 CPU 核心數(shù)
    public ShardParallelProcessor() {
        this.threadCount = Runtime.getRuntime().availableProcessors();
        this.executor = Executors.newFixedThreadPool(threadCount);
    }
    // 構(gòu)造函數(shù):自定義線程數(shù)
    public ShardParallelProcessor(int threadCount) {
        this.threadCount = threadCount;
        this.executor = Executors.newFixedThreadPool(threadCount);
    }
    /**
     * 并行處理分片:每個分片執(zhí)行 processor 邏輯
     * @param shards 分片列表
     * @param processor 分片處理邏輯(函數(shù)式接口)
     * @return 合并后的處理結(jié)果
     */
    public List<R> process(List<List<T>> shards, ShardProcessor<T, R> processor) {
        try {
            // 提交所有分片任務(wù),并行執(zhí)行
            return shards.stream()
                    .map(shard -> executor.submit(() -> processor.process(shard)))
                    .map(future -> {
                        try {
                            return future.get(); // 獲取分片處理結(jié)果
                        } catch (Exception e) {
                            throw new RuntimeException("分片處理失敗", e);
                        }
                    })
                    .flatMap(List::stream) // 合并所有分片結(jié)果
                    .collect(Collectors.toList());
        } finally {
            // 關(guān)閉線程池
            executor.shutdown();
            try {
                if (!executor.awaitTermination(1, TimeUnit.HOURS)) {
                    executor.shutdownNow();
                }
            } catch (InterruptedException e) {
                executor.shutdownNow();
            }
        }
    }
    /**
     * 分片處理函數(shù)式接口
     */
    @FunctionalInterface
    public interface ShardProcessor<T, R> {
        List<R> process(List<T> shard);
    }
    // 測試:并行統(tǒng)計分片數(shù)據(jù)中偶數(shù)的個數(shù)
    public static void main(String[] args) {
        // 1. 生成 100 萬條數(shù)據(jù)并分片
        List<Integer> bigList = new ArrayList<>(1_000_000);
        for (int i = 0; i < 1_000_000; i++) {
            bigList.add(i);
        }
        ListSharder<Integer> sharder = new ListSharder<>(bigList, 10_000);
        List<List<Integer>> shards = sharder.shard();
        // 2. 并行處理:統(tǒng)計每個分片的偶數(shù)個數(shù)
        ShardParallelProcessor<Integer, Integer> processor = new ShardParallelProcessor<>();
        List<Integer> shardEvenCounts = processor.process(shards, shard -> {
            // 每個分片統(tǒng)計偶數(shù)個數(shù)
            long count = shard.stream().filter(num -> num % 2 == 0).count();
            return List.of((int) count);
        });
        // 3. 合并結(jié)果
        int totalEvenCount = shardEvenCounts.stream().mapToInt(Integer::intValue).sum();
        System.out.println("100 萬條數(shù)據(jù)中偶數(shù)的個數(shù):" + totalEvenCount); // 輸出:500000
    }
}

4.3 分布式分片處理(基于 MapReduce 思想)

當數(shù)據(jù)量達到億級別時,單機分片已無法滿足需求,需采用分布式分片架構(gòu)(如 Hadoop MapReduce、Spark),核心思想:

  1. 分片:將分布式存儲(如 HDFS、MySQL 分庫分表)中的數(shù)據(jù)拆分為多個分片
  2. 映射(Map):多個節(jié)點并行處理各自分片,輸出中間結(jié)果
  3. 歸約(Reduce):匯總所有節(jié)點的中間結(jié)果,得到最終結(jié)果

Java 集合可作為分布式分片的“本地處理單元”,配合分布式框架實現(xiàn)大規(guī)模數(shù)據(jù)處理。

五、分布式場景中集合的數(shù)據(jù)一致性與傳輸優(yōu)化

在分布式系統(tǒng)中,集合數(shù)據(jù)的傳輸和一致性維護是核心挑戰(zhàn),需解決“數(shù)據(jù)序列化、網(wǎng)絡(luò)傳輸效率、分布式一致性”三大問題。

5.1 集合數(shù)據(jù)序列化優(yōu)化

集合數(shù)據(jù)在網(wǎng)絡(luò)中傳輸時需序列化,選擇高效的序列化框架可降低傳輸開銷,常用框架包括:

  • Jackson:JSON 序列化,可讀性強,適用于中小數(shù)據(jù)量
  • Protostuff:二進制序列化,效率高、體積小,適用于大數(shù)據(jù)量
  • Kryo:高性能二進制序列化,適用于分布式緩存、RPC 傳輸

以下是基于 Protostuff 的集合序列化工具類:

import io.protostuff.LinkedBuffer;
import io.protostuff.ProtostuffIOUtil;
import io.protostuff.Schema;
import io.protostuff.runtime.RuntimeSchema;
import java.util.List;
import java.util.Map;
/**
 * 集合序列化工具類(基于 Protostuff)
 */
public class CollectionSerializer {
    // 線程局部變量:避免緩沖區(qū)競爭
    private static final ThreadLocal<LinkedBuffer> BUFFER = ThreadLocal.withInitial(() -> LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE));
    /**
     * 序列化 List
     */
    public static <T> byte[] serializeList(List<T> list, Class<T> clazz) {
        if (list == null || list.isEmpty()) {
            return new byte[0];
        }
        Schema<T> schema = RuntimeSchema.getSchema(clazz);
        LinkedBuffer buffer = BUFFER.get();
        try {
            return ProtostuffIOUtil.toByteArray(list, schema, buffer);
        } finally {
            buffer.clear(); // 清空緩沖區(qū)
        }
    }
    /**
     * 反序列化 List
     */
    public static <T> List<T> deserializeList(byte[] data, Class<T> clazz) {
        if (data == null || data.length == 0) {
            return List.of();
        }
        Schema<T> schema = RuntimeSchema.getSchema(clazz);
        List<T> list = schema.newMessage().getClass().isAssignableFrom(List.class) ? 
                (List<T>) schema.newMessage() : new ArrayList<>();
        ProtostuffIOUtil.mergeFrom(data, (T) list, schema);
        return list;
    }
    /**
     * 序列化 Map(簡化實現(xiàn),實際需自定義 Schema)
     */
    public static <K, V> byte[] serializeMap(Map<K, V> map, Class<K> keyClazz, Class<V> valueClazz) {
        // 實際開發(fā)中需為 Map 自定義 Schema,此處簡化為 JSON 序列化(僅作示例)
        try {
            return new com.alibaba.fastjson.JSONObject().toJSONBytes(map);
        } catch (Exception e) {
            throw new RuntimeException("Map 序列化失敗", e);
        }
    }
    /**
     * 反序列化 Map
     */
    public static <K, V> Map<K, V> deserializeMap(byte[] data, Class<K> keyClazz, Class<V> valueClazz) {
        if (data == null || data.length == 0) {
            return Map.of();
        }
        // 對應(yīng)序列化邏輯,簡化為 JSON 反序列化
        try {
            return com.alibaba.fastjson.JSONObject.parseObject(data, new com.alibaba.fastjson.TypeReference<Map<K, V>>() {});
        } catch (Exception e) {
            throw new RuntimeException("Map 反序列化失敗", e);
        }
    }
}

5.2 分布式集合數(shù)據(jù)一致性保障

分布式場景中,多個節(jié)點同時操作集合數(shù)據(jù)會導致一致性問題,常用解決方案:

  1. 分布式鎖:通過 Redis 分布式鎖、ZooKeeper 鎖等,保證同一時間只有一個節(jié)點修改數(shù)據(jù)
  2. 版本控制:為集合數(shù)據(jù)添加版本號,修改時校驗版本,避免覆蓋過期數(shù)據(jù)
  3. 最終一致性:基于消息隊列異步同步數(shù)據(jù),允許短時間不一致,最終達到一致

以下是基于 Redis 分布式鎖的集合修改示例:

import redis.clients.jedis.Jedis;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
/**
 * 分布式集合修改:基于 Redis 分布式鎖保證一致性
 */
public class DistributedListModifier<T> {
    private final Jedis jedis;
    private final String listKey; // Redis 中 List 的 key
    private final String lockKey; // 分布式鎖 key
    private final long lockTimeout; // 鎖超時時間(毫秒)
    public DistributedListModifier(Jedis jedis, String listKey, long lockTimeout) {
        this.jedis = jedis;
        this.listKey = listKey;
        this.lockKey = "lock:" + listKey;
        this.lockTimeout = lockTimeout;
    }
    /**
     * 向分布式 List 中添加元素(線程安全)
     */
    public boolean addElement(T element) {
        String lockValue = UUID.randomUUID().toString();
        try {
            // 1. 獲取分布式鎖
            boolean locked = tryLock(lockValue);
            if (!locked) {
                return false; // 獲取鎖失敗,返回重試
            }
            // 2. 序列化元素并添加到 Redis List
            byte[] data = CollectionSerializer.serializeList(List.of(element), (Class<T>) element.getClass());
            jedis.rpush(listKey.getBytes(), data);
            return true;
        } finally {
            // 3. 釋放鎖
            releaseLock(lockValue);
        }
    }
    /**
     * 獲取分布式鎖
     */
    private boolean tryLock(String lockValue) {
        String result = jedis.set(lockKey, lockValue, "NX", "PX", lockTimeout);
        return "OK".equals(result);
    }
    /**
     * 釋放分布式鎖(防止誤釋放)
     */
    private void releaseLock(String lockValue) {
        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
        jedis.eval(script, List.of(lockKey), List.of(lockValue));
    }
}

5.3 集合傳輸優(yōu)化技巧

  • 分片傳輸:大數(shù)據(jù)量集合拆分后分批傳輸,避免單次傳輸過大導致超時
  • 壓縮傳輸:序列化后對數(shù)據(jù)進行壓縮(如 GZIP),減少網(wǎng)絡(luò)帶寬占用
  • 增量傳輸:僅傳輸新增/修改的元素,而非整個集合,降低傳輸開銷
  • 延遲加載:分布式場景中,先傳輸集合元數(shù)據(jù)(如大小、分片信息),按需加載具體數(shù)據(jù)

六、實戰(zhàn)案例:基于集合的規(guī)則引擎設(shè)計

規(guī)則引擎是業(yè)務(wù)系統(tǒng)的核心組件,用于動態(tài)管理業(yè)務(wù)規(guī)則(如風控規(guī)則、促銷規(guī)則),基于集合框架可實現(xiàn)輕量級規(guī)則引擎,支持規(guī)則的動態(tài)添加、匹配和執(zhí)行。

6.1 需求分析

設(shè)計一個促銷規(guī)則引擎,支持以下功能:

  1. 動態(tài)添加促銷規(guī)則(如滿減、折扣、贈品)
  2. 根據(jù)訂單信息匹配符合條件的規(guī)則
  3. 執(zhí)行規(guī)則并返回促銷結(jié)果
  4. 支持規(guī)則優(yōu)先級(高優(yōu)先級規(guī)則先執(zhí)行)

6.2 設(shè)計思路

  • 規(guī)則接口(PromotionRule):定義規(guī)則的匹配條件和執(zhí)行邏輯
  • 規(guī)則引擎(RuleEngine):使用 TreeSet 存儲規(guī)則(按優(yōu)先級排序),提供規(guī)則添加、匹配、執(zhí)行方法
  • 訂單上下文(OrderContext):封裝訂單信息,作為規(guī)則匹配和執(zhí)行的入?yún)?/li>

6.3 代碼實現(xiàn)

6.3.1 訂單上下文類(OrderContext.java)

import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;
/**
 * 訂單上下文:封裝規(guī)則匹配所需的訂單信息
 */
public class OrderContext {
    private final String orderId;
    private final BigDecimal totalAmount; // 訂單總金額
    private final List<String> productIds; // 商品 ID 列表
    private final int memberLevel; // 會員等級
    // 構(gòu)造函數(shù)
    public OrderContext(String orderId, BigDecimal totalAmount, List<String> productIds, int memberLevel) {
        this.orderId = Objects.requireNonNull(orderId);
        this.totalAmount = Objects.requireNonNull(totalAmount);
        this.productIds = Objects.requireNonNull(productIds);
        this.memberLevel = memberLevel;
    }
    // getter
    public String getOrderId() {
        return orderId;
    }
    public BigDecimal getTotalAmount() {
        return totalAmount;
    }
    public List<String> getProductIds() {
        return productIds;
    }
    public int getMemberLevel() {
        return memberLevel;
    }
}

6.3.2 促銷規(guī)則接口(PromotionRule.java)

/**
 * 促銷規(guī)則接口:所有規(guī)則需實現(xiàn)此接口
 */
public interface PromotionRule {
    /**
     * 規(guī)則優(yōu)先級:數(shù)值越大,優(yōu)先級越高
     */
    int getPriority();
    /**
     * 規(guī)則匹配:判斷訂單是否滿足規(guī)則條件
     */
    boolean match(OrderContext context);
    /**
     * 執(zhí)行規(guī)則:返回促銷結(jié)果
     */
    PromotionResult execute(OrderContext context);
    /**
     * 促銷結(jié)果封裝
     */
    record PromotionResult(String ruleName, BigDecimal discountAmount, String gift) {}
}

6.3.3 具體規(guī)則實現(xiàn)(滿減規(guī)則、折扣規(guī)則)

import java.math.BigDecimal;
/**
 * 滿減規(guī)則:滿 1000 減 200
 */
public class FullReduceRule implements PromotionRule {
    @Override
    public int getPriority() {
        return 2; // 優(yōu)先級:2
    }
    @Override
    public boolean match(OrderContext context) {
        // 訂單金額 ≥1000 元
        return context.getTotalAmount().compareTo(new BigDecimal("1000")) >= 0;
    }
    @Override
    public PromotionResult execute(OrderContext context) {
        return new PromotionResult("滿1000減200", new BigDecimal("200"), "無");
    }
}
/**
 * 會員折扣規(guī)則:VIP 會員 9 折
 */
public class MemberDiscountRule implements PromotionRule {
    @Override
    public int getPriority() {
        return 1; // 優(yōu)先級:1(低于滿減規(guī)則)
    }
    @Override
    public boolean match(OrderContext context) {
        // 會員等級 ≥3(VIP 會員)
        return context.getMemberLevel() >= 3;
    }
    @Override
    public PromotionResult execute(OrderContext context) {
        BigDecimal discount = context.getTotalAmount().multiply(new BigDecimal("0.1"));
        return new PromotionResult("VIP 9折", discount, "無");
    }
}
/**
 * 贈品規(guī)則:購買指定商品送贈品
 */
public class GiftRule implements PromotionRule {
    private final String targetProductId;
    private final String gift;
    public GiftRule(String targetProductId, String gift) {
        this.targetProductId = targetProductId;
        this.gift = gift;
    }
    @Override
    public int getPriority() {
        return 3; // 優(yōu)先級:3(最高)
    }
    @Override
    public boolean match(OrderContext context) {
        // 包含指定商品
        return context.getProductIds().contains(targetProductId);
    }
    @Override
    public PromotionResult execute(OrderContext context) {
        return new PromotionResult("購買指定商品送贈品", BigDecimal.ZERO, gift);
    }
}

6.3.4 規(guī)則引擎類(RuleEngine.java)

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;
/**
 * 規(guī)則引擎:基于 TreeSet 按優(yōu)先級管理規(guī)則
 */
public class RuleEngine {
    // 存儲規(guī)則:TreeSet 按優(yōu)先級降序排序(優(yōu)先級越高越先執(zhí)行)
    private final TreeSet<PromotionRule> rules = new TreeSet<>(Comparator.comparingInt(PromotionRule::getPriority).reversed());
    /**
     * 添加規(guī)則
     */
    public void addRule(PromotionRule rule) {
        rules.add(rule);
    }
    /**
     * 匹配并執(zhí)行規(guī)則:返回所有符合條件的規(guī)則結(jié)果
     */
    public List<PromotionResult> executeRules(OrderContext context) {
        List<PromotionResult> results = new ArrayList<>();
        for (PromotionRule rule : rules) {
            if (rule.match(context)) {
                results.add(rule.execute(context));
                // 若為排他規(guī)則,可在此處 break(本案例支持多規(guī)則疊加)
            }
        }
        return results;
    }
    // 測試
    public static void main(String[] args) {
        // 1. 初始化規(guī)則引擎并添加規(guī)則
        RuleEngine engine = new RuleEngine();
        engine.addRule(new FullReduceRule());
        engine.addRule(new MemberDiscountRule());
        engine.addRule(new GiftRule("P001", "保溫杯"));
        // 2. 構(gòu)造訂單上下文(滿 1000 元、VIP 會員、包含 P001 商品)
        OrderContext context = new OrderContext(
                "ORDER001",
                new BigDecimal("1500"),
                List.of("P001", "P002"),
                3
        );
        // 3. 執(zhí)行規(guī)則
        List<PromotionResult> results = engine.executeRules(context);
        // 4. 輸出結(jié)果(按優(yōu)先級排序:贈品規(guī)則 → 滿減規(guī)則 → 折扣規(guī)則)
        System.out.println("訂單 " + context.getOrderId() + " 匹配的促銷規(guī)則:");
        for (PromotionResult result : results) {
            System.out.printf("規(guī)則:%s,折扣金額:%s,贈品:%s%n",
                    result.ruleName(), result.discountAmount(), result.gift());
        }
    }
}

6.4 測試結(jié)果與案例總結(jié)

6.4.1 測試輸出

訂單 ORDER001 匹配的促銷規(guī)則:
規(guī)則:購買指定商品送贈品,折扣金額:0,贈品:保溫杯
規(guī)則:滿1000減200,折扣金額:200,贈品:無
規(guī)則:VIP 9折,折扣金額:150.00,贈品:無

6.4.2 案例總結(jié)

? 核心技術(shù)亮點:

  1. 集合選型:使用 TreeSet 存儲規(guī)則,自動按優(yōu)先級排序,無需手動維護順序
  2. 接口抽象:定義 PromotionRule 接口,支持規(guī)則擴展(新增規(guī)則無需修改引擎代碼)
  3. 靈活性:支持多規(guī)則疊加執(zhí)行,可通過修改比較器或添加排他標記支持排他規(guī)則
  4. 可擴展性:規(guī)則可動態(tài)添加/刪除,適用于業(yè)務(wù)規(guī)則頻繁變化的場景

? 擴展方向:

  • 規(guī)則持久化:將規(guī)則存儲到數(shù)據(jù)庫,支持動態(tài)配置和熱更新
  • 規(guī)則條件表達式:使用 EL 表達式或腳本語言(如 Groovy)定義規(guī)則條件,更靈活
  • 規(guī)則執(zhí)行監(jiān)控:記錄規(guī)則執(zhí)行日志和結(jié)果,便于排查問題和優(yōu)化規(guī)則

七、本章小結(jié)

本章聚焦 Java 集合框架的高級應(yīng)用與架構(gòu)設(shè)計,從緩存架構(gòu)、設(shè)計模式融合、大數(shù)據(jù)量處理、分布式適配到業(yè)務(wù)組件設(shè)計,全面覆蓋復雜場景的實踐方案,核心要點回顧如下:

  1. 緩存架構(gòu):基于 LinkedHashMap 實現(xiàn) LRU+TTL 本地緩存,結(jié)合分布式緩存設(shè)計多級緩存架構(gòu),兼顧性能和一致性。
  2. 設(shè)計模式融合:裝飾器模式增強集合功能,享元模式復用重復對象,迭代器模式自定義遍歷邏輯,提升代碼擴展性。
  3. 大數(shù)據(jù)量處理:通過集合分片存儲控制內(nèi)存,結(jié)合線程池并行處理提升效率,分布式場景下可擴展為 MapReduce 架構(gòu)。
  4. 分布式適配:優(yōu)化集合序列化和傳輸效率,基于分布式鎖保證數(shù)據(jù)一致性,適用于微服務(wù)和分布式系統(tǒng)。
  5. 業(yè)務(wù)組件設(shè)計:基于集合框架實現(xiàn)輕量級規(guī)則引擎,支持規(guī)則動態(tài)管理和靈活擴展,可復用至各類業(yè)務(wù)系統(tǒng)。

通過本章學習,讀者應(yīng)能跳出“基礎(chǔ) API 使用”的層面,站在架構(gòu)設(shè)計的角度運用集合框架,解決高并發(fā)、大數(shù)據(jù)量、分布式等復雜場景的問題,設(shè)計出高性能、可擴展、易維護的 Java 應(yīng)用。集合框架作為 Java 開發(fā)的基礎(chǔ)工具,其靈活運用是高級開發(fā)工程師的核心能力之一,后續(xù)可結(jié)合具體業(yè)務(wù)場景持續(xù)深化實踐。

到此這篇關(guān)于Java 集合框架高級應(yīng)用與架構(gòu)設(shè)計方案的文章就介紹到這了,更多相關(guān)Java 集合框架實戰(zhàn)應(yīng)用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • springboot項目父子多模塊打包方式

    springboot項目父子多模塊打包方式

    這篇文章主要介紹了springboot項目父子多模塊打包方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • SpringBoot整合WebSocket實現(xiàn)聊天室流程全解

    SpringBoot整合WebSocket實現(xiàn)聊天室流程全解

    WebSocket協(xié)議是基于TCP的一種新的網(wǎng)絡(luò)協(xié)議。本文將通過SpringBoot集成WebSocket實現(xiàn)簡易聊天室,對大家的學習或者工作具有一定的參考學習價值,感興趣的可以了解一下
    2023-01-01
  • Spring 父類變量注入失敗的解決

    Spring 父類變量注入失敗的解決

    這篇文章主要介紹了Spring 父類變量注入失敗的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • SpringBoot中雙token實現(xiàn)無感刷新

    SpringBoot中雙token實現(xiàn)無感刷新

    本文介紹雙Token無感刷新機制,前端React與后端SpringBoot實現(xiàn),采用HttpOnly Cookie和短期Token設(shè)計,具有一定的參考價值,感興趣的可以了解一下
    2025-07-07
  • java追加寫入txt文件的方法總結(jié)

    java追加寫入txt文件的方法總結(jié)

    在本篇文章里我們給大家整理了關(guān)于java如何追加寫入txt文件的方法和代碼,需要的朋友們可以參考下。
    2020-02-02
  • spring Data jpa簡介_動力節(jié)點Java學院整理

    spring Data jpa簡介_動力節(jié)點Java學院整理

    這篇文章主要介紹了spring Data jpa簡介的相關(guān)資料,需要的朋友可以參考下
    2017-09-09
  • 通過Java實現(xiàn)RSA加密與驗證的方法詳解

    通過Java實現(xiàn)RSA加密與驗證的方法詳解

    RSA是一種非對稱加密算法,是目前廣泛應(yīng)用于加密和數(shù)字簽名領(lǐng)域的一種加密算法,本文主要講述如何通過Java實現(xiàn)RSA加密與驗證,應(yīng)用場景為與其他平臺對接接口時,通過RSA加密和解密驗證請求的有效性,在對接時雙方互換公鑰,需要的朋友可以參考下
    2023-12-12
  • Java繼承的實現(xiàn)與繼承限制分析

    Java繼承的實現(xiàn)與繼承限制分析

    這篇文章主要介紹了Java繼承的實現(xiàn)與繼承限制,結(jié)合具體實例形式分析了Java繼承的定義、實現(xiàn)以及繼承的相關(guān)限制,需要的朋友可以參考下
    2019-01-01
  • SpringBoot如何使用applicationContext.xml配置文件

    SpringBoot如何使用applicationContext.xml配置文件

    這篇文章主要介紹了SpringBoot使用applicationContext.xml配置文件,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • MyBatis使用嵌套查詢collection和association的實現(xiàn)

    MyBatis使用嵌套查詢collection和association的實現(xiàn)

    本文詳細介紹了使用MyBatis框架進行數(shù)據(jù)庫操作時,如何利用collection標簽實現(xiàn)一對多的嵌套查詢和使用association標簽實現(xiàn)一對一的嵌套查詢,感興趣的可以了解一下
    2024-09-09

最新評論

黑河市| 都昌县| 台湾省| 赤水市| 龙江县| 焦作市| 瓮安县| 佛学| 临颍县| 遂昌县| 许昌县| 班玛县| 始兴县| 泰兴市| 博兴县| 新河县| 滨州市| 赫章县| 井研县| 怀来县| 通辽市| 广西| 胶州市| 新乡市| 祁连县| 乾安县| 枣强县| 高台县| 绥化市| 磴口县| 定结县| 元江| 大竹县| 平舆县| 阳高县| 镇坪县| 观塘区| 石景山区| 应用必备| 东安县| 延吉市|