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

基于Java的guava開源庫(kù)工具類

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

基于Java的guava開源庫(kù)工具類

前言:

平時(shí)我們都會(huì)封裝一些處理緩存或其他的小工具。但每個(gè)人都封裝一次,重復(fù)造輪子,有點(diǎn)費(fèi)時(shí)間。有沒有一些好的工具庫(kù)推薦-guava。guava是谷歌基于java封裝好的開源庫(kù),它的性能、實(shí)用性,比我們自己造的輪子更好,畢竟谷歌出品,下面介紹下幾個(gè)常用的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 在實(shí)際場(chǎng)景中有著非常廣泛的使用,通常情況下如果遇到需要大量時(shí)間計(jì)算或者緩存值的場(chǎng)景,就應(yīng)當(dāng)將值保存到緩存中。LoadingCache 和 ConcurrentMap 類似,但又不盡相同。最大的不同是 ConcurrentMap 會(huì)永久的存儲(chǔ)所有的元素值直到他們被顯示的移除,但是 LoadingCache 會(huì)為了保持內(nèi)存使用合理會(huì)根據(jù)配置自動(dòng)將過(guò)期值移除

通常情況下,Guava caching 適用于以下場(chǎng)景:

  • 花費(fèi)一些內(nèi)存來(lái)?yè)Q取速度
  • 一些 key 會(huì)被不止一次被調(diào)用
  • 緩存內(nèi)容有限,不會(huì)超過(guò)內(nèi)存空間的值,Guava caches 不會(huì)存儲(chǔ)內(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) 緩存池大小,在緩存項(xiàng)接近該大小時(shí), Guava開始回收舊的緩存項(xiàng)
weakValues() 設(shè)置value的存儲(chǔ)引用是虛引用
softValues() 設(shè)置value的存儲(chǔ)引用是軟引用
expireAfterWrite(long duration, TimeUnit unit) 設(shè)置時(shí)間對(duì)象沒有被寫則對(duì)象從內(nèi)存中刪除(在另外的線程里面不定期維護(hù))
expireAfterAccess(long duration, TimeUnit unit) 設(shè)置時(shí)間對(duì)象沒有被讀/寫訪問則對(duì)象從內(nèi)存中刪除(在另外的線程里面不定期維護(hù))
refreshAfterWrite(long duration, TimeUnit unit) 和expireAfterWrite類似,不過(guò)不立馬移除key,而是在下次更新時(shí)刷新,這段時(shí)間可能會(huì)返回舊值
removalListener( RemovalListener<? super K1, ? super V1> listener) 監(jiān)聽器,緩存項(xiàng)被移除時(shí)會(huì)觸發(fā)
build(CacheLoader<? super K1, V1> loader) 當(dāng)數(shù)據(jù)不存在時(shí),則使用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的特點(diǎn)其實(shí)就是可以包含有幾個(gè)重復(fù)Key的value,可以put進(jìn)入多個(gè)不同value但是相同的key,但是又不會(huì)覆蓋前面的內(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 有一個(gè)相對(duì)有用的場(chǎng)景,就是跟蹤每種對(duì)象的數(shù)量,所以可以用來(lái)進(jìn)行數(shù)量統(tǒng)計(jì)

示例:

//MultiSet: 無(wú)序+可重復(fù)   count()方法獲取單詞的次數(shù)  增強(qiáng)了可讀性+操作簡(jiǎn)單
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的鍵必須唯一,值也必須唯一,可以實(shí)現(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是存儲(chǔ)值
  • 新增數(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對(duì)應(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的事件處理機(jī)制,是設(shè)計(jì)模式中的觀察者模式(生產(chǎn)/消費(fèi)者編程模型)的優(yōu)雅實(shí)現(xiàn)。對(duì)于事件監(jiān)聽和發(fā)布訂閱模式
  • EventBus內(nèi)部實(shí)現(xiàn)原理不復(fù)雜,EventBus內(nèi)部會(huì)維護(hù)一個(gè)Multimap<Class<?>, Subscriber> map,key就代表消息對(duì)應(yīng)的類(不同消息不同類,區(qū)分不同的消息)、value是一個(gè)Subscriber,Subscriber其實(shí)就是對(duì)應(yīng)消息處理者。如果有消息發(fā)布就去這個(gè)map里面找到這個(gè)消息對(duì)應(yīng)的Subscriber去執(zhí)行

使用示例:

@Data
@AllArgsConstructor
public class OrderMessage {
    String message;
}
//使用 @Subscribe 注解,表明使用dealWithEvent 方法處理 OrderMessage類型對(duì)應(yīng)的消息
//可以注解多個(gè)方法,不同的方法 處理不同的對(duì)象消息
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("邏輯代碼運(yùn)行耗時(shí):"+nanos);

9、Files文件操作

數(shù)據(jù)寫入

File newFile = new File("D:/text.txt");
Files.write("this is a test".getBytes(), newFile);
//再次寫入會(huì)把之前的內(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) 移動(dòng)文件
Files.touch(File file) 創(chuàng)建或者更新文件的時(shí)間戳
Files.getFileExtension(String file) 獲得文件的擴(kuò)展名
Files.getNameWithoutExtension(String file) 獲得不帶擴(kuò)展名的文件名
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ù)熱時(shí)間,從第一次acquire 或 tryAcquire 執(zhí)行開時(shí)計(jì)算
public static RateLimiter create(double permitsPerSecond, Duration warmupPeriod)
//獲取一個(gè)令牌,阻塞,返回阻塞時(shí)間
public double acquire()
//獲取 permits 個(gè)令牌,阻塞,返回阻塞時(shí)間
public double acquire(int permits)
//獲取一個(gè)令牌,超時(shí)返回
public boolean tryAcquire(Duration timeout)
////獲取 permits 個(gè)令牌,超時(shí)返回
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

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

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 失敗后重試間隔時(shí)間
withStopStrategy 停止策略
withBlockStrategy 阻塞策略BlockStrategy
withAttemptTimeLimiter 執(zhí)行時(shí)間限制策略
retryIfException 發(fā)生異常,則重試
retryIfRuntimeException 發(fā)生RuntimeException異常,則重試
retryIfExceptionOfType(Class<? extends Throwable> ex) 發(fā)生ex異常,則重試
retryIfException(Predicate<Throwable> exceptionPredicate) 對(duì)異常判斷,是否重試
retryIfResult(Predicate<V> resultPredicate) 對(duì)返回結(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開源庫(kù)工具類的詳細(xì)內(nèi)容,更多關(guān)于guava開源庫(kù)工具類的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!希望大家以后多多支持腳本之家!

相關(guān)文章

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

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

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

    java如何用遞歸方法求階乘

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

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

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

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

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

    java split()使用方法解析

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

    RabbitMQ消息拒絕如何解決

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

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

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

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

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

    初步理解Java的泛型特性

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

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

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

最新評(píng)論