广告
返回顶部
首页 > 资讯 > 后端开发 > Python >基于Java的guava开源库工具类
  • 664
分享到

基于Java的guava开源库工具类

2024-04-02 19:04:59 664人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录基于Java的guava开源库工具类1、guava的Maven配置引入 2、LoadinGCache 3、Multimap 和 MultiSet4、BiMap5、Tab

基于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 会为了保持内存使用合理会根据配置自动将过期值移除

通常情况下,Guava caching 适用于以下场景:

  • 花费一些内存来换取速度
  • 一些 key 会被不止一次被调用
  • 缓存内容有限,不会超过内存空间的值,Guava caches 不会存储内容到文件或者到服务器外部,如果有此类需求考虑使用 Memcached, Redis

LoadingCache 不能缓存 null key
CacheBuilder 构造 LoadingCache 参数介绍

CacheBuilder 方法参数 描述
initialCapacity(int initialCapacity) 缓存池的初始大小
concurrencyLevel(int concurrencyLevel) 设置并发
maximumSize(long maximumSize) 缓存池大小,在缓存项接近该大小时, Guava开始回收旧的缓存项
weakValues() 设置value的存储引用是虚引用
softValues() 设置value的存储引用是软引用
expireAfterWrite(long duration, TimeUnit unit) 设置时间对象没有被写则对象从内存中删除(在另外的线程里面不定期维护)
expireAfterAccess(long duration, TimeUnit unit) 设置时间对象没有被读/写访问则对象从内存中删除(在另外的线程里面不定期维护)
refreshAfterWrite(long duration, TimeUnit unit) 和expireAfterWrite类似,不过不立马移除key,而是在下次更新时刷新,这段时间可能会返回旧值
removalListener( RemovalListener<? super K1, ? super V1> listener) 监听器,缓存项被移除时会触发
build(CacheLoader<? super K1, V1> loader) 当数据不存在时,则使用loader加载数据

LoadingCache V get(K key), 获取缓存值,如果键不存在值,将调用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,但是又不会覆盖前面的内容

示例:


//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 有一个相对有用的场景,就是跟踪每种对象的数量,所以可以用来进行数量统计

示例:


//MultiSet: 无序+可重复   count()方法获取单词的次数  增强了可读性+操作简单
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的键必须唯一,值也必须唯一,可以实现value和key互转

示例:


BiMap<Integer,String> biMap = HashBiMap.create();
biMap.put(1,"lwl");
biMap.put(2,"csc");
BiMap<String, Integer> map = biMap.inverse(); // value和key互转
map.forEach((v, k) -> System.out.println(v + "-" + k));

5、Table

  • Table<R,C,V> table = HasHBasedTable.create();,由泛型可以看出,table由双主键R(行),C(列)共同决定,V是存储值
  • 新增数据:table.put(R,C,V)
  • 获取数据:V v = table.get(R,C)
  • 遍历数据: 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


// 不可变集合的创建
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());;
-------------结果-------------
{c=3}
{b=(2, 20)}
{a=1}
{d=4}

7、EventBus

  • EventBus是Guava的事件处理机制,是设计模式中的观察者模式(生产/消费者编程模型)的优雅实现。对于事件监听和发布订阅模式
  • EventBus内部实现原理不复杂,EventBus内部会维护一个Multimap<Class<?>, Subscriber> map,key就代表消息对应的类(不同消息不同类,区分不同的消息)、value是一个Subscriber,Subscriber其实就是对应消息处理者。如果有消息发布就去这个map里面找到这个消息对应的Subscriber去执行

使用示例:


@Data
@AllArgsConstructor
public class OrderMessage {
    String message;
}
//使用 @Subscribe 注解,表明使用dealWithEvent 方法处理 OrderMessage类型对应的消息
//可以注解多个方法,不同的方法 处理不同的对象消息
public class OrderEventListener {
    @Subscribe
    public void dealWithEvent(OrderMessage event) {
        System.out.println("内容:" + event.getMessage());
    }
}
-------------------------------------
// new AsyncEventBus(String identifier, Executor executor);
EventBus eventBus = new EventBus("lwl"); 
eventBus.reGISter(new OrderEventListener());
// 发布消息
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文件操作

数据写入


File newFile = new File("D:/text.txt");
Files.write("this is a test".getBytes(), newFile);
//再次写入会把之前的内容冲掉
Files.write("csc".getBytes(), newFile);
//追加写
Files.append("lwl", newFile, Charset.defaultCharset());


文本数据读取


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) 删除文件夹下的内容(包括文件与子文件夹)
Files.deleteRecursively(File file) 删除文件或者文件夹
Files.move(File from, File to) 移动文件
Files.touch(File file) 创建或者更新文件的时间戳
Files.getFileExtension(String file) 获得文件的扩展名
Files.getNameWithoutExtension(String file) 获得不带扩展名的文件名
Files.map(File file, MapMode mode) 获取内存映射buffer

10、RateLimiter


//RateLimiter 构造方法,每秒限流permitsPerSecond
public static RateLimiter create(double permitsPerSecond) 
//每秒限流 permitsPerSecond,warmupPeriod 则是数据初始预热时间,从第一次acquire 或 tryAcquire 执行开时计算
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");
---------------  结果 -------------------------
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,花了三秒时间去预热数据,在第五次到第八次的acquire耗时趋于平滑

11、Guava Retry

maven引入


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

RetryerBuilder 构造方法

RetryerBuilder方法 描述
withRetryListener 重试监听器
withWaitStrategy 失败后重试间隔时间
withStopStrategy 停止策略
withBlockStrategy 阻塞策略BlockStrategy
withAttemptTimeLimiter 执行时间限制策略
retryIfException 发生异常,则重试
retryIfRuntimeException 发生RuntimeException异常,则重试
retryIfExceptionOfType(Class<? extends Throwable> ex) 发生ex异常,则重试
retryIfException(Predicate<Throwable> exceptionPredicate) 对异常判断,是否重试
retryIfResult(Predicate<V> resultPredicate) 对返回结果判断,是否重试


Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
    .retryIfException()
    .retryIfResult(Predicates.equalTo(false))
    .withAttemptTimeLimiter(AttemptTimeLimiters.fixedTimeLimit(1, TimeUnit.SECONDS))
    .withStopStrategy(StopStrategies.stopAfterAttempt(5))
    .build();
//Retryer调用                
retryer.call(() -> true);

以上就是基于Java的guava开源库工具类的详细内容,更多关于guava开源库工具类的资料请关注编程网其它相关文章!希望大家以后多多支持编程网!

--结束END--

本文标题: 基于Java的guava开源库工具类

本文链接: https://www.lsjlt.com/news/134437.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 基于Java的guava开源库工具类
    目录基于Java的guava开源库工具类1、guava的maven配置引入 2、LoadingCache 3、Multimap 和 MultiSet4、BiMap5、Tab...
    99+
    2022-11-12
  • 基于Java如何实现进制转换工具类
    这篇文章主要介绍了基于Java如何实现进制转换工具类的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇基于Java如何实现进制转换工具类文章都会有所收获,下面我们一起来看看吧。背景最近有个发送短信的功能,需要在短信...
    99+
    2023-07-05
  • 基于Java手写一个好用的FTP操作工具类
    目录前言windows服务器搭建FTP服务工具类方法代码展示使用示例前言 网上百度了很多FTP的java 工具类,发现文章代码都比较久远,且代码臃肿,即使搜到了代码写的还可以的,封装...
    99+
    2022-11-13
  • 有哪些开源的Java IDE 工具
    本篇内容介绍了“有哪些开源的Java IDE 工具”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!BlueJBlueJ 为 Java 初学者提...
    99+
    2023-06-16
  • Java基于装饰者模式实现的图片工具类实例【附demo源码下载】
    本文实例讲述了Java基于装饰者模式实现的图片工具类。分享给大家供大家参考,具体如下:ImgUtil.java:package util;import java.io.File;import java.util.List;public in...
    99+
    2023-05-31
    java 装饰者模式 图片
  • 基于Java实现的大乐透号码生成器工具类
    目录一、题目二、解题思路三、代码详解一、题目 大乐透是中国体育彩票的一种玩法,是国家体育总局体彩中心为适应市场发展需要,丰富体育彩票的市场结构,经过慎重研究和广泛的市场调研,于200...
    99+
    2022-11-13
    Java大乐透号码生成器 Java 乐透号码生成 Java 号码生成
  • 基于Java实现进制转换工具类的示例代码
    目录背景原理十进制A转换为N进制RN进制R转换为十进制A应用延伸背景 最近有个发送短信的功能,需要在短信中带有详情链接,链接中带有对应信息且要有校验功能,然而短信是按字数收费的,所以...
    99+
    2023-02-19
    Java进制转换工具类 Java进制转换
  • 关于Java日期工具类的编写
    目录Java日期工具类编写JavaCalendar日历类的时间操作日期工具类Java日期工具类编写 将字符串转换为对应日期 Date date = simpleDateFormat....
    99+
    2023-05-18
    Java 日期 Java工具类 Java日期工具类
  • Java开发中常用的工具类库有哪些
    这篇文章主要讲解了“Java开发中常用的工具类库有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java开发中常用的工具类库有哪些”吧! Java开发...
    99+
    2022-10-19
  • 基于node的cli工具怎么开发使用
    本篇内容介绍了“基于node的cli工具怎么开发使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!背景公司内部有维护admin和h6两套基础...
    99+
    2023-07-05
  • 基于node的cli工具开发使用详解
    目录前言背景功能特性效果预览插件开发使用实现原理使用到的工具package.jsonweb-cli.tsservice.tscreate.ts前言 如果文章对你有帮助的话,记得一键...
    99+
    2023-05-13
    node cli开发工具 node cli
  • 基于Docker封装的开发包工具介绍
    本篇内容介绍了“基于Docker封装的开发包工具介绍”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!基于 Docker1.12+ (Docke...
    99+
    2023-06-04
  • Hutool Java工具类库_ExcelUtil的使用
    目录Hutool Java工具类库_ExcelUtil依赖ExcelUtilExcelReaderExcelWriterjava解析Excel使用hutool工具类Hutool Ja...
    99+
    2022-11-12
  • 基于Spring的上下文工具类ApplicationContextUtil是怎样的
    基于Spring的上下文工具类ApplicationContextUtil是怎样的,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Spring上下文工具类 Applicati...
    99+
    2023-06-25
  • 基于Python的科学占卜工具开发过程
    目录背景前置知识基础原理如何产生卦象开发源代码背景 一直以来,中式占卜都是基于算命先生手工实现,程序繁琐(往往需要沐浴、计算天时、静心等等流程)。准备工作复杂(通常需要铜钱等道具),...
    99+
    2022-11-10
  • 开源的数据库管理工具有哪些
    这篇文章主要介绍了开源的数据库管理工具有哪些,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。工欲善其事必先利其器,想要玩溜数据库,不妨去试试本...
    99+
    2022-10-18
  • 开箱即用的开源工具库xijs示例详解
    目录正文引入单元测试正文 xijs 是我2年前开源的一款面向复杂业务场景的 javascript 工具库, 包含了业务开发中常用的: 浏览器相关函...
    99+
    2023-03-09
    开箱即用开源工具库xijs 开源工具库xijs
  • 基于Java的数据库结构维护工具Dzo 3.0的示例分析
    基于Java的数据库结构维护工具Dzo 3.0的示例分析,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Dzo 是一个数据库的小工具,用以帮助维护不同的数据库结构,当前支持 My...
    99+
    2023-06-17
  • 适用于Linux的优秀开源缓存工具有哪些
    本篇内容介绍了“适用于Linux的优秀开源缓存工具有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!什么是缓存或内容缓存缓存(或内容缓存)...
    99+
    2023-06-16
  • 基于java的中文分词工具ANSJ怎么使用
    这篇文章主要讲解了“基于java的中文分词工具ANSJ怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“基于java的中文分词工具ANSJ怎么使用”吧!ANSJ这是一个基于n-Gram+...
    99+
    2023-06-19
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作