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

基于Java的guava開源庫工具類

 更新時間:2021年09月02日 15:00:03   作者:麗大佬的小跟班  
guava是谷歌基于java封裝好的開源庫,這篇文章主要通過介紹幾個好用的guava工具類,感興趣的朋友可以參考下面文章內(nèi)容

基于Java的guava開源庫工具類

前言:

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

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

1、guava的maven配置引入 

<dependency>
  <groupId>com.google.guava</groupId>
  <artifactId>guava</artifactId>
  <version>27.0-jre</version>
 </dependency>

2、LoadingCache

 LoadingCache 在實際場景中有著非常廣泛的使用,通常情況下如果遇到需要大量時間計算或者緩存值的場景,就應當將值保存到緩存中。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) 當數(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);

3、Multimap 和 MultiSet

Multimap的特點其實就是可以包含有幾個重復Key的value,可以put進入多個不同value但是相同的key,但是又不會覆蓋前面的內(nèi)容

示例:

//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 有一個相對有用的場景,就是跟蹤每種對象的數(shù)量,所以可以用來進行數(shù)量統(tǒng)計

示例:

//MultiSet: 無序+可重復   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"));
---------------------------
3
2

4、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));

5、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對應的value
System.out.println(tables.get("csc","lwl"));

6、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");

set的交集, 并集, 差集

HashSet setA = newHashSet(1, 2, 3, 4, 5);  
HashSet setB = newHashSet(4, 5, 6, 7, 8); 
//并集
SetView union = Sets.union(setA, setB);   
//差集 setA-setB
SetView 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 相同的 entry
System.out.println(mapDifference.entriesInCommon());
//mapA 和 mapB key相同的value不同的 entry
System.out.println(mapDifference.entriesDiffering());
//只存在 mapA 的 entry
System.out.println(mapDifference.entriesOnlyOnLeft());
//只存在 mapB 的 entry
System.out.println(mapDifference.entriesOnlyOnRight());;
-------------結(jié)果-------------
{c=3}
{b=(2, 20)}
{a=1}
{d=4}

7、EventBus

  • EventBus是Guava的事件處理機制,是設(shè)計模式中的觀察者模式(生產(chǎn)/消費者編程模型)的優(yōu)雅實現(xiàn)。對于事件監(jiān)聽和發(fā)布訂閱模式
  • EventBus內(nèi)部實現(xiàn)原理不復雜,EventBus內(nèi)部會維護一個Multimap<Class<?>, Subscriber> map,key就代表消息對應的類(不同消息不同類,區(qū)分不同的消息)、value是一個Subscriber,Subscriber其實就是對應消息處理者。如果有消息發(fā)布就去這個map里面找到這個消息對應的Subscriber去執(zhí)行

使用示例:

@Data
@AllArgsConstructor
public class OrderMessage {
    String message;
}
//使用 @Subscribe 注解,表明使用dealWithEvent 方法處理 OrderMessage類型對應的消息
//可以注解多個方法,不同的方法 處理不同的對象消息
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"));

8、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);

9、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());


文本數(shù)據(jù)讀取

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) 刪除文件夾下的內(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

10、RateLimiter

//RateLimiter 構(gòu)造方法,每秒限流permitsPerSecond
public static RateLimiter create(double permitsPerSecond) 
//每秒限流 permitsPerSecond,warmupPeriod 則是數(shù)據(jù)初始預熱時間,從第一次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)


使用示例

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.0s
get one permit cost time: 1.331672s
get one permit cost time: 0.998392s
get one permit cost time: 0.666014s
get one permit cost time: 0.498514s
get one permit cost time: 0.498918s
get one permit cost time: 0.499151s
get one permit cost time: 0.488548s

  • 因為RateLimiter滯后處理的,所以第一次無論取多少都是零秒
  • 可以看到前四次的acquire,花了三秒時間去預熱數(shù)據(jù),在第五次到第八次的acquire耗時趨于平滑

11、Guava Retry

maven引入

<dependency>
  <groupId>com.github.rholder</groupId>
  <artifactId>guava-retrying</artifactId>
  <version>2.0.0</version>
</dependency>

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);

以上就是基于Java的guava開源庫工具類的詳細內(nèi)容,更多關(guān)于guava開源庫工具類的資料請關(guān)注腳本之家其它相關(guān)文章!希望大家以后多多支持腳本之家!

相關(guān)文章

  • 將一個數(shù)組按照固定大小進行拆分成數(shù)組的方法

    將一個數(shù)組按照固定大小進行拆分成數(shù)組的方法

    下面小編就為大家?guī)硪黄獙⒁粋€數(shù)組按照固定大小進行拆分成數(shù)組的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-11-11
  • Java實現(xiàn)Kruskal算法的示例代碼

    Java實現(xiàn)Kruskal算法的示例代碼

    Kruskal算法是一種用來尋找最小生成樹的算法,由Joseph Kruskal在1956年發(fā)表。用來解決同樣問題的還有Prim算法和Boruvka算法等。本文將介紹用Java語言實現(xiàn)Kruskal算法的示例代碼,需要的可以參考一下
    2022-07-07
  • 使用eclipse打包Maven項目的實現(xiàn)步驟

    使用eclipse打包Maven項目的實現(xiàn)步驟

    本文主要介紹了使用eclipse打包Maven項目的實現(xiàn)步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-03-03
  • 在IntelliJ IDEA中使用gulp的方法步驟(圖文)

    在IntelliJ IDEA中使用gulp的方法步驟(圖文)

    這篇文章主要介紹了在IntelliJ IDEA中使用gulp的方法步驟(圖文),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-01-01
  • Java?垃圾回收超詳細講解記憶集和卡表

    Java?垃圾回收超詳細講解記憶集和卡表

    卡表就是記憶集的一種具體實現(xiàn),它定義了記憶集的記錄精度、與堆內(nèi)存的映射關(guān)系等。?關(guān)于卡表與記憶集的關(guān)系,不妨按照Java語言中HashMap與Map的關(guān)系來類比理解。記憶集是一種用于記錄從非收集區(qū)域指向收集區(qū)域的指針集合的抽象數(shù)據(jù)結(jié)構(gòu)
    2022-04-04
  • Java判斷主機是否能ping通代碼實例

    Java判斷主機是否能ping通代碼實例

    這篇文章主要介紹了Java判斷主機是否能ping通代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-01-01
  • springboot運行時新增/更新外部接口的實現(xiàn)方法

    springboot運行時新增/更新外部接口的實現(xiàn)方法

    這篇文章主要介紹了springboot運行時新增/更新外部接口的實現(xiàn)方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03
  • springboot 如何解決cross跨域請求的問題

    springboot 如何解決cross跨域請求的問題

    這篇文章主要介紹了springboot 如何解決cross跨域請求的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java封裝好的mail包發(fā)送電子郵件的類

    Java封裝好的mail包發(fā)送電子郵件的類

    本文給大家分享了2個java封裝好的mail包發(fā)送電子郵件的類,并附上使用方法,小伙伴們可以根據(jù)自己的需求自由選擇。
    2016-01-01
  • Spring設(shè)計模式中代理模式詳細講解

    Spring設(shè)計模式中代理模式詳細講解

    如何實現(xiàn)在不修改源碼的基礎(chǔ)上實現(xiàn)代碼功能的增強呢?spring為我們提供了代理模式。所謂的代理模式通俗來說就是一個中介,它給某一個對象提供一個代理對象,并由代理對象控制原對象的引用,從而實現(xiàn)在不修改源碼的基礎(chǔ)上實現(xiàn)代碼功能的增強
    2023-01-01

最新評論

潍坊市| 龙里县| 古交市| 陇南市| 翼城县| 泗洪县| 瑞金市| 洪江市| 康定县| 凭祥市| 宣汉县| 天水市| 仁怀市| 灯塔市| 长治市| 临夏市| 瑞昌市| 新沂市| 平泉县| 宣威市| 深圳市| 鹿泉市| 临武县| 台安县| 宾阳县| 富裕县| 六枝特区| 陆川县| 天津市| 察雅县| 浦东新区| 静宁县| 文登市| 葵青区| 武鸣县| 麻阳| 古丈县| 石嘴山市| 遂平县| 阿拉善左旗| 盐津县|