前言
平時(shí)我們都會(huì)封裝一些處理緩存或其他的小工具。但每個(gè)人都封裝一次,重復(fù)造輪子,有點(diǎn)費(fèi)時(shí)間。有沒(méi)有一些好的工具庫(kù)推薦-guava。guava是谷歌基于java封裝好的開源庫(kù),它的性能、實(shí)用性,比我們自己造的輪子更好,畢竟谷歌出品,下面介紹下幾個(gè)常用的guava工具類
關(guān)注公眾號(hào),一起交流,微信搜一搜: 潛行前行
guava的maven配置引入
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>27.0-jre</version> </dependency>復(fù)制代碼
LoadingCache
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ì)象沒(méi)有被寫則對(duì)象從內(nèi)存中刪除(在另外的線程里面不定期維護(hù)) |
expireAfterAccess(long duration, TimeUnit unit) | 設(shè)置時(shí)間對(duì)象沒(méi)有被讀/寫訪問(wèn)則對(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<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: 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: 無(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"));---------------------------32復(fù)制代碼
BiMap
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
// 雙鍵的Map Map--> Table-->rowKey+columnKey+value Table<String, String, Integer> tables = HashbasedTable.create();tables.put("csc", "lwl", 1);//row+column對(duì)應(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
@Data@AllArgsConstructorpublic 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"));復(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("邏輯代碼運(yùn)行耗時(shí):"+nanos);復(fù)制代碼
Files文件操作
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());復(fù)制代碼
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) | 移動(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 |
RateLimiter
//RateLimiter 構(gòu)造方法,每秒限流permitsPerSecondpublic 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)復(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ù)制代碼
Guava Retry
<dependency> <groupId>com.github.rholder</groupId> <artifactId>guava-retrying</artifactId> <version>2.0.0</version></dependency>復(fù)制代碼
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);復(fù)制代碼
作者:潛行前行
鏈接:https://juejin.cn/post/6974202216768864264
來(lái)源:掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。