欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于Java的guava開源庫工具類

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

基于Java的guava開源庫工具類

前言:

平時我們都會封裝一些處理緩存或其他的小工具。但每個人都封裝一次,重復(fù)造輪子,有點費時間。有沒有一些好的工具庫推薦-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 在實際場景中有著非常廣泛的使用,通常情況下如果遇到需要大量時間計算或者緩存值的場景,就應(yī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) 當數(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的特點其實就是可以包含有幾個重復(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]


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"));
---------------------------
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對應(yīng)的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)原理不復(fù)雜,EventBus內(nèi)部會維護一個Multimap<Class<?>, Subscriber> map,key就代表消息對應(yīng)的類(不同消息不同類,區(qū)分不同的消息)、value是一個Subscriber,Subscriber其實就是對應(yīng)消息處理者。如果有消息發(fā)布就去這個map里面找到這個消息對應(yīng)的Subscriber去執(zhí)行

使用示例:

@Data
@AllArgsConstructor
public 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"));

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) 復(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

10、RateLimiter

//RateLimiter 構(gòu)造方法,每秒限流permitsPerSecond
public 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)


使用示例

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,花了三秒時間去預(yù)熱數(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)文章

  • Java和MySQL數(shù)據(jù)庫中關(guān)于小數(shù)的保存問題詳析

    Java和MySQL數(shù)據(jù)庫中關(guān)于小數(shù)的保存問題詳析

    在Java和MySQL中小數(shù)的精度可能會受到限制,如float類型的小數(shù)只能精確到6-7位,double類型也只能精確到15-16位,這篇文章主要給大家介紹了關(guān)于Java和MySQL數(shù)據(jù)庫中關(guān)于小數(shù)的保存問題,需要的朋友可以參考下
    2024-01-01
  • java如何用遞歸方法求階乘

    java如何用遞歸方法求階乘

    這篇文章主要介紹了java 用遞歸方法求階乘的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Java中sort排序函數(shù)實例詳解

    Java中sort排序函數(shù)實例詳解

    我們經(jīng)常使用java中的sort排序,確實好用,但是其中原理大多數(shù)人都是不了解的,下面這篇文章主要給大家介紹了關(guān)于Java中sort排序函數(shù)的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-06-06
  • java實現(xiàn)即賦值也判斷的寫法示例

    java實現(xiàn)即賦值也判斷的寫法示例

    這篇文章主要為大家介紹了java實現(xiàn)即賦值也判斷的寫法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • java split()使用方法解析

    java split()使用方法解析

    這篇文章主要介紹了java split()使用方法解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友可以參考下
    2020-02-02
  • RabbitMQ消息拒絕如何解決

    RabbitMQ消息拒絕如何解決

    這篇文章主要介紹了RabbitMQ消息拒絕如何解決問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • 詳解java中float與double的區(qū)別

    詳解java中float與double的區(qū)別

    這篇文章主要介紹了JAVA中float與double的區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧
    2019-04-04
  • Java網(wǎng)絡(luò)編程基礎(chǔ)詳解

    Java網(wǎng)絡(luò)編程基礎(chǔ)詳解

    網(wǎng)絡(luò)編程是指編寫運行在多個設(shè)備(計算機)的程序,這些設(shè)備都通過網(wǎng)絡(luò)連接起來。本文介紹了一些網(wǎng)絡(luò)編程基礎(chǔ)的概念,并用Java來實現(xiàn)TCP和UDP的Socket的編程,來讓讀者更好的了解其原理
    2021-08-08
  • 初步理解Java的泛型特性

    初步理解Java的泛型特性

    這篇文章主要介紹了Java的泛型特性,是Java入門學(xué)習中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-11-11
  • FastDFS分布式文件系統(tǒng)環(huán)境搭建及安裝過程解析

    FastDFS分布式文件系統(tǒng)環(huán)境搭建及安裝過程解析

    這篇文章主要介紹了FastDFS分布式文件系統(tǒng)環(huán)境搭建及安裝過程解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友可以參考下
    2020-08-08

最新評論