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

二維碼
企資網(wǎng)

掃一掃關(guān)注

當(dāng)前位置: 首頁 » 企資快報 » 企業(yè) » 正文

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

放大字體  縮小字體 發(fā)布日期:2021-09-13 13:46:09    作者:啊丟    瀏覽次數(shù):17
導(dǎo)讀

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

前言

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

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

    關(guān)注公眾號,一起交流,微信搜一搜: 潛行前行

    guava的maven配置引入

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

    LoadingCache

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

    CacheBuilder 方法參數(shù)

    描述

    initialCapacity(int initialCapacity)

    緩存池的初始大小

    concurrencyLevel(int concurrencyLevel)

    設(shè)置并發(fā)數(shù)

    maximumSize(long maximumSize)

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

    weakValues()

    設(shè)置value的存儲引用是虛引用

    softValues()

    設(shè)置value的存儲引用是軟引用

    expireAfterWrite(long duration, TimeUnit unit)

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

    expireAfterAccess(long duration, TimeUnit unit)

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

    refreshAfterWrite(long duration, TimeUnit unit)

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

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

    監(jiān)聽器,緩存項被移除時會觸發(fā)

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

    當(dāng)數(shù)據(jù)不存在時,則使用loader加載數(shù)據(jù)

  • LoadingCache V get(K key), 獲取緩存值,如果鍵不存在值,將調(diào)用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);復(fù)制代碼

    Multimap 和 MultiSet

  • Multimap的特點其實就是可以包含有幾個重復(fù)Key的value,可以put進入多個不同value但是相同的key,但是又不會覆蓋前面的內(nèi)容
  • 示例
    //Multimap: key-value  key可以重復(fù),value也可重復(fù)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]復(fù)制代碼
  • MultiSet 有一個相對有用的場景,就是跟蹤每種對象的數(shù)量,所以可以用來進行數(shù)量統(tǒng)計
  • 示例
    //MultiSet: 無序+可重復(fù)   count()方法獲取單詞的次數(shù)  增強了可讀性+操作簡單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復(fù)制代碼

    BiMap

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

    Table

  • Table<R,C,V> table = HashbasedTable.create();,由泛型可以看出,table由雙主鍵R(行),C(列)共同決定,V是存儲值
  • 新增數(shù)據(jù):table.put(R,C,V)
  • 獲取數(shù)據(jù):V v = table.get(R,C)
  • 遍歷數(shù)據(jù): 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對應(yīng)的valueSystem.out.println(tables.get("csc","lwl"));復(fù)制代碼

    Sets和Maps

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

    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);  復(fù)制代碼

    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());;-------------結(jié)果-------------{c=3}{b=(2, 20)}{a=1}{d=4}復(fù)制代碼

    EventBus

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

    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);復(fù)制代碼

    Files文件操作

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

    方法

    描述

    Files.copy(File from, File to)

    復(fù)制文件

    Files.deleteDirectoryContents(File directory)

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

    Files.deleteRecursively(File file)

    刪除文件或者文件夾

    Files.move(File from, File to)

    移動文件

    Files.touch(File file)

    創(chuàng)建或者更新文件的時間戳

    Files.getFileExtension(String file)

    獲得文件的擴展名

    Files.getNameWithoutExtension(String file)

    獲得不帶擴展名的文件名

    Files.map(File file, MapMode mode)

    獲取內(nèi)存映射buffer

    RateLimiter

    //RateLimiter 構(gòu)造方法,每秒限流permitsPerSecondpublic static RateLimiter create(double permitsPerSecond) //每秒限流 permitsPerSecond,warmupPeriod 則是數(shù)據(jù)初始預(yù)熱時間,從第一次acquire 或 tryAcquire 執(zhí)行開時計算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)復(fù)制代碼
  • 使用示例
    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");---------------  結(jié)果 -------------------------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復(fù)制代碼
  • 因為RateLimiter滯后處理的,所以第一次無論取多少都是零秒
  • 可以看到前四次的acquire,花了三秒時間去預(yù)熱數(shù)據(jù),在第五次到第八次的acquire耗時趨于平滑

    Guava Retry

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

    RetryerBuilder方法

    描述

    withRetryListener

    重試監(jiān)聽器

    withWaitStrategy

    失敗后重試間隔時間

    withStopStrategy

    停止策略

    withBlockStrategy

    阻塞策略BlockStrategy

    withAttemptTimeLimiter

    執(zhí)行時間限制策略

    retryIfException

    發(fā)生異常,則重試

    retryIfRuntimeException

    發(fā)生RuntimeException異常,則重試

    retryIfExceptionOfType(Class<? extends Throwable> ex)

    發(fā)生ex異常,則重試

    retryIfException(Predicate<Throwable> exceptionPredicate)

    對異常判斷,是否重試

    retryIfResult(Predicate<V> resultPredicate)

    對返回結(jié)果判斷,是否重試

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


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

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

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

    粵ICP備16078936號

    微信

    關(guān)注
    微信

    微信二維碼

    WAP二維碼

    客服

    聯(lián)系
    客服

    聯(lián)系客服:

    在線QQ: 303377504

    客服電話: 020-82301567

    E_mail郵箱: weilaitui@qq.com

    微信公眾號: weishitui

    客服001 客服002 客服003

    工作時間:

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

    反饋

    用戶
    反饋

    主站蜘蛛池模板: 国产日韩欧美亚洲 | 午夜宅男永久在线观看 | 特级片毛片 | 日本欧美一区二区三区 | 夜间福利视频 | 瑟瑟网站在线观看 | 天天干天天摸天天操 | 今天免费中文字幕视频 | 久99国产在线视频 | 一区二区三区四区精品视频 | 久久综合丝袜长腿丝袜 | 国产精品嫩草影院88v | 小明永久播放平台领域2015 | 国产1区2区在线观看 | 中文字幕欧美在线观看 | 黄色片日韩 | 一本大道香蕉高清久久 | 欧美一级片在线视频 | 一女多男高h | 免费一级国产大片 | 成人高清视频在线观看大全 | 欧美亚洲国产精品久久 | 一个人看的在线www片高清 | 老人与老人a级毛片视频 | 美女视频久久 | 操美女免费看 | 国产精品23p | 国产成人精品一区二区三区 | 小明tv | 高清成人爽a毛片免费网站 高清国产精品久久久久 | 午夜性福利视频 | 亚洲欧美日韩国产精品久久 | 免费在线观看h片 | 成人在线视频播放 | 日韩免费影院 | 亚洲国产天堂在线mv网站 | 亚洲精品第一页 | 最近中文2019字幕在线观看 | 亚洲精品午夜aaa级久久久久 | 日韩黄色片在线观看 | 在线播放国产一区 |