免费人成动漫在线播放r18-免费人成观看在线网-免费人成黄页在线观看日本-免费人成激情视频在线观看冫-jlzzjlzz亚洲大全-jlzzjlzz亚洲日本

二維碼
企資網

掃一掃關注

當前位置: 首頁 » 企資快報 » 企業 » 正文

工具篇_介紹幾個好用的guava工具類

放大字體  縮小字體 發布日期:2021-09-13 13:46:09    作者:啊丟    瀏覽次數:13
導讀

前言平時我們都會封裝一些處理緩存或其他的小工具。但每個人都封裝一次,重復造輪子,有點費時間。有沒有一些好的工具庫推薦-guava。guava是谷歌基于java封裝好的開源庫,它的性能、實用性,比我們自己造的輪子更好

前言

平時我們都會封裝一些處理緩存或其他的小工具。但每個人都封裝一次,重復造輪子,有點費時間。有沒有一些好的工具庫推薦-guava。guava是谷歌基于java封裝好的開源庫,它的性能、實用性,比我們自己造的輪子更好,畢竟谷歌出品,下面介紹下幾個常用的guava工具類

  • LoadingCache(本地緩存)
  • Multimap 和 Multiset
  • BiMap
  • Table(表)
  • Sets和Maps(交并差)
  • EventBus(事件)
  • StopWatch(秒表)
  • Files(文件操作)
  • RateLimiter(限流器)
  • Guava Retry(重試)

    關注公眾號,一起交流,微信搜一搜: 潛行前行

    guava的maven配置引入

    <dependency>  <groupId>com.google.guava</groupId>  <artifactId>guava</artifactId>  <version>27.0-jre</version> </dependency>復制代碼

    LoadingCache

  • LoadingCache 在實際場景中有著非常廣泛的使用,通常情況下如果遇到需要大量時間計算或者緩存值的場景,就應當將值保存到緩存中。LoadingCache 和 ConcurrentMap 類似,但又不盡相同。最大的不同是 ConcurrentMap 會永久的存儲所有的元素值直到他們被顯示的移除,但是 LoadingCache 會為了保持內存使用合理會根據配置自動將過期值移除
  • 通常情況下,Guava caching 適用于以下場景:
  • 花費一些內存來換取速度
  • 一些 key 會被不止一次被調用
  • 緩存內容有限,不會超過內存空間的值,Guava caches 不會存儲內容到文件或者到服務器外部,如果有此類需求考慮使用 Memcached, Redis
  • LoadingCache 不能緩存 null key
  • CacheBuilder 構造 LoadingCache 參數介紹

    CacheBuilder 方法參數

    描述

    initialCapacity(int initialCapacity)

    緩存池的初始大小

    concurrencyLevel(int concurrencyLevel)

    設置并發數

    maximumSize(long maximumSize)

    緩存池大小,在緩存項接近該大小時, Guava開始回收舊的緩存項

    weakValues()

    設置value的存儲引用是虛引用

    softValues()

    設置value的存儲引用是軟引用

    expireAfterWrite(long duration, TimeUnit unit)

    設置時間對象沒有被寫則對象從內存中刪除(在另外的線程里面不定期維護)

    expireAfterAccess(long duration, TimeUnit unit)

    設置時間對象沒有被讀/寫訪問則對象從內存中刪除(在另外的線程里面不定期維護)

    refreshAfterWrite(long duration, TimeUnit unit)

    和expireAfterWrite類似,不過不立馬移除key,而是在下次更新時刷新,這段時間可能會返回舊值

    removalListener( RemovalListener<? super K1, ? super V1> listener)

    監聽器,緩存項被移除時會觸發

    build(CacheLoader<? super K1, V1> loader)

    當數據不存在時,則使用loader加載數據

  • LoadingCache V get(K key), 獲取緩存值,如果鍵不存在值,將調用CacheLoader的load方法加載新值到該鍵中
  • 示例
    LoadingCache<Integer,Long> cacheMap = CacheBuilder.newBuilder().initialCapacity(10)    .concurrencyLevel(10)    .expireAfterAccess(Duration.ofSeconds(10))    .weakValues()    .recordStats()    .removalListener(new RemovalListener<Integer,Long>(){        @Override        public void onRemoval(RemovalNotification<Integer, Long> notification) {            System.out.println(notification.getValue());        }    })    .build(new CacheLoader<Integer,Long>(){        @Override        public Long load(Integer key) throws Exception {            return System.currentTimeMillis();        }    });cacheMap.get(1);復制代碼

    Multimap 和 MultiSet

  • Multimap的特點其實就是可以包含有幾個重復Key的value,可以put進入多個不同value但是相同的key,但是又不會覆蓋前面的內容
  • 示例
    //Multimap: key-value  key可以重復,value也可重復Multimap<String, String> multimap = ArrayListMultimap.create();multimap.put("csc","1");multimap.put("lwl","1");multimap.put("csc","1");multimap.put("lwl","one");System.out.println(multimap.get("csc"));System.out.println(multimap.get("lwl"));---------------------------[1, 1][1, one]復制代碼
  • MultiSet 有一個相對有用的場景,就是跟蹤每種對象的數量,所以可以用來進行數量統計
  • 示例
    //MultiSet: 無序+可重復   count()方法獲取單詞的次數  增強了可讀性+操作簡單Multiset<String> set = HashMultiset.create();set.add("csc");set.add("lwl");set.add("csc");System.out.println(set.size());System.out.println(set.count("csc"));---------------------------32復制代碼

    BiMap

  • BiMap的鍵必須唯一,值也必須唯一,可以實現value和key互轉
  • 示例
    BiMap<Integer,String> biMap = HashBiMap.create();biMap.put(1,"lwl");biMap.put(2,"csc");BiMap<String, Integer> map = biMap.inverse(); // value和key互轉map.forEach((v, k) -> System.out.println(v + "-" + k));復制代碼

    Table

  • Table<R,C,V> table = HashbasedTable.create();,由泛型可以看出,table由雙主鍵R(行),C(列)共同決定,V是存儲值
  • 新增數據:table.put(R,C,V)
  • 獲取數據:V v = table.get(R,C)
  • 遍歷數據: Set<R> set = table.rowKeySet(); Set<C> set = table.columnKeySet();   
  • 示例
    // 雙鍵的Map Map--> Table-->rowKey+columnKey+value  Table<String, String, Integer> tables = HashbasedTable.create();tables.put("csc", "lwl", 1);//row+column對應的valueSystem.out.println(tables.get("csc","lwl"));復制代碼

    Sets和Maps

    // 不可變集合的創建ImmutableList<String> iList = ImmutableList.of("csc", "lwl");ImmutableSet<String> iSet = ImmutableSet.of("csc", "lwl");ImmutableMap<String, String> iMap = ImmutableMap.of("csc", "hello", "lwl", "world");復制代碼

    set的交集, 并集, 差集

    HashSet setA = newHashSet(1, 2, 3, 4, 5);  HashSet setB = newHashSet(4, 5, 6, 7, 8); //并集SetView union = Sets.union(setA, setB);   //差集 setA-setBSetView difference = Sets.difference(setA, setB);  //交集SetView intersection = Sets.intersection(setA, setB);  復制代碼

    map的交集,并集,差集

    HashMap<String, Integer> mapA = Maps.newHashMap();mapA.put("a", 1);mapA.put("b", 2);mapA.put("c", 3);HashMap<String, Integer> mapB = Maps.newHashMap();mapB.put("b", 20);mapB.put("c", 3);mapB.put("d", 4);MapDifference<String, Integer> mapDifference = Maps.difference(mapA, mapB);//mapA 和 mapB 相同的 entrySystem.out.println(mapDifference.entriesInCommon());//mapA 和 mapB key相同的value不同的 entrySystem.out.println(mapDifference.entriesDiffering());//只存在 mapA 的 entrySystem.out.println(mapDifference.entriesOnlyOnLeft());//只存在 mapB 的 entrySystem.out.println(mapDifference.entriesOnlyOnRight());;-------------結果-------------{c=3}{b=(2, 20)}{a=1}{d=4}復制代碼

    EventBus

  • EventBus是Guava的事件處理機制,是設計模式中的觀察者模式(生產/消費者編程模型)的優雅實現。對于事件監聽和發布訂閱模式
  • EventBus內部實現原理不復雜,EventBus內部會維護一個Multimap<Class<?>, Subscriber> map,key就代表消息對應的類(不同消息不同類,區分不同的消息)、value是一個Subscriber,Subscriber其實就是對應消息處理者。如果有消息發布就去這個map里面找到這個消息對應的Subscriber去執行
  • 使用示例
    @Data@AllArgsConstructorpublic class OrderMessage {    String message;}//使用 @Subscribe 注解,表明使用dealWithEvent 方法處理 OrderMessage類型對應的消息//可以注解多個方法,不同的方法 處理不同的對象消息public class OrderEventListener {    @Subscribe    public void dealWithEvent(OrderMessage event) {        System.out.println("內容:" + event.getMessage());    }}-------------------------------------// new AsyncEventBus(String identifier, Executor executor);EventBus eventBus = new EventBus("lwl"); eventBus.register(new OrderEventListener());// 發布消息eventBus.post(new OrderMessage("csc"));復制代碼

    StopWatch

    Stopwatch stopwatch = Stopwatch.createStarted();for(int i=0; i<100000; i++){    // do some thing}long nanos = stopwatch.elapsed(TimeUnit.MILLISECONDS);System.out.println("邏輯代碼運行耗時:"+nanos);復制代碼

    Files文件操作

  • 數據寫入
    File newFile = new File("D:/text.txt");Files.write("this is a test".getBytes(), newFile);//再次寫入會把之前的內容沖掉Files.write("csc".getBytes(), newFile);//追加寫Files.append("lwl", newFile, Charset.defaultCharset());復制代碼
  • 文本數據讀取
    File newFile = new File("E:/text.txt");List<String> lines = Files.readLines(newFile, Charset.defaultCharset());復制代碼
  • 其他操作

    方法

    描述

    Files.copy(File from, File to)

    復制文件

    Files.deleteDirectoryContents(File directory)

    刪除文件夾下的內容(包括文件與子文件夾)

    Files.deleteRecursively(File file)

    刪除文件或者文件夾

    Files.move(File from, File to)

    移動文件

    Files.touch(File file)

    創建或者更新文件的時間戳

    Files.getFileExtension(String file)

    獲得文件的擴展名

    Files.getNameWithoutExtension(String file)

    獲得不帶擴展名的文件名

    Files.map(File file, MapMode mode)

    獲取內存映射buffer

    RateLimiter

    //RateLimiter 構造方法,每秒限流permitsPerSecondpublic static RateLimiter create(double permitsPerSecond) //每秒限流 permitsPerSecond,warmupPeriod 則是數據初始預熱時間,從第一次acquire 或 tryAcquire 執行開時計算public static RateLimiter create(double permitsPerSecond, Duration warmupPeriod)//獲取一個令牌,阻塞,返回阻塞時間public double acquire()//獲取 permits 個令牌,阻塞,返回阻塞時間public double acquire(int permits)//獲取一個令牌,超時返回public boolean tryAcquire(Duration timeout)////獲取 permits 個令牌,超時返回public boolean tryAcquire(int permits, Duration timeout)復制代碼
  • 使用示例
    RateLimiter limiter = RateLimiter.create(2, 3, TimeUnit.SECONDS);System.out.println("get one permit cost time: " + limiter.acquire(1) + "s");System.out.println("get one permit cost time: " + limiter.acquire(1) + "s");System.out.println("get one permit cost time: " + limiter.acquire(1) + "s");System.out.println("get one permit cost time: " + limiter.acquire(1) + "s");System.out.println("get one permit cost time: " + limiter.acquire(1) + "s");System.out.println("get one permit cost time: " + limiter.acquire(1) + "s");System.out.println("get one permit cost time: " + limiter.acquire(1) + "s");System.out.println("get one permit cost time: " + limiter.acquire(1) + "s");---------------  結果 -------------------------get one permit cost time: 0.0sget one permit cost time: 1.331672sget one permit cost time: 0.998392sget one permit cost time: 0.666014sget one permit cost time: 0.498514sget one permit cost time: 0.498918sget one permit cost time: 0.499151sget one permit cost time: 0.488548s復制代碼
  • 因為RateLimiter滯后處理的,所以第一次無論取多少都是零秒
  • 可以看到前四次的acquire,花了三秒時間去預熱數據,在第五次到第八次的acquire耗時趨于平滑

    Guava Retry

  • maven引入
    <dependency>  <groupId>com.github.rholder</groupId>  <artifactId>guava-retrying</artifactId>  <version>2.0.0</version></dependency>復制代碼
  • RetryerBuilder 構造方法

    RetryerBuilder方法

    描述

    withRetryListener

    重試監聽器

    withWaitStrategy

    失敗后重試間隔時間

    withStopStrategy

    停止策略

    withBlockStrategy

    阻塞策略BlockStrategy

    withAttemptTimeLimiter

    執行時間限制策略

    retryIfException

    發生異常,則重試

    retryIfRuntimeException

    發生RuntimeException異常,則重試

    retryIfExceptionOfType(Class<? extends Throwable> ex)

    發生ex異常,則重試

    retryIfException(Predicate<Throwable> exceptionPredicate)

    對異常判斷,是否重試

    retryIfResult(Predicate<V> resultPredicate)

    對返回結果判斷,是否重試

    Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()    .retryIfException()    .retryIfResult(Predicates.equalTo(false))    .withAttemptTimeLimiter(AttemptTimeLimiters.fixedTimeLimit(1, TimeUnit.SECONDS))    .withStopStrategy(StopStrategies.stopAfterAttempt(5))    .build();//Retryer調用                retryer.call(() -> true);復制代碼
  • spring也有對應的重試機制,相關文章可以看看重試框架Guava-Retry和spring-Retry


    作者:潛行前行
    鏈接:https://juejin.cn/post/6974202216768864264
    來源:掘金
    著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

  •  
    (文/啊丟)
    免責聲明
    本文僅代表作發布者:啊丟個人觀點,本站未對其內容進行核實,請讀者僅做參考,如若文中涉及有違公德、觸犯法律的內容,一經發現,立即刪除,需自行承擔相應責任。涉及到版權或其他問題,請及時聯系我們刪除處理郵件:weilaitui@qq.com。
     

    Copyright ? 2016 - 2025 - 企資網 48903.COM All Rights Reserved 粵公網安備 44030702000589號

    粵ICP備16078936號

    微信

    關注
    微信

    微信二維碼

    WAP二維碼

    客服

    聯系
    客服

    聯系客服:

    在線QQ: 303377504

    客服電話: 020-82301567

    E_mail郵箱: weilaitui@qq.com

    微信公眾號: weishitui

    客服001 客服002 客服003

    工作時間:

    周一至周五: 09:00 - 18:00

    反饋

    用戶
    反饋

    主站蜘蛛池模板: 成人91视频 | 日韩欧美国产视频 | 色黄啪啪网18以下勿进动画 | 一个人在线看的免费视频 | 全黄大全大色全免费大片 | 亚洲另类z0zx | 操你.com | 亚洲视频在线观看 | 五月开心六月伊人色婷婷 | bl男男全肉高h集合 bl男男全肉高h车 | 一级欧美在线的视频 | 国产成人啪精品视频免费网 | www.成人在线 | 久精品在线观看 | www.av色| 怡红院成人永久免费看 | 少妇人妻挤奶水中文视频毛片 | 男女视频免费网站 | 国产丝袜视频在线 | 欧美视频导航 | 成人小视频在线观看免费 | 欧美成人免费一区在线播放 | 91精品观看91久久久久久 | 免费一级真人毛片 | 理论毛片| 欧美日韩图区 | 亚洲成熟xxxx| 天天操天天艹 | 国产成人手机视频 | 369看片你懂的永久免费 | 天天干天天干天天 | 老湿影院免费体验区 | 亚洲日产综合欧美一区二区 | 亚洲第一免费播放区 | 欧美日韩aa一级视频 | 手机小视频在线观看 | 开心成人激情 | 午夜免费在线观看 | 日韩一级欧美一级在线观看 | 在线亚洲精品国产成人二区 | 日本日韩欧美 |