广告
返回顶部
首页 > 资讯 > 后端开发 > Python >java的Guava工具包介绍
  • 765
分享到

java的Guava工具包介绍

2024-04-02 19:04:59 765人浏览 独家记忆

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

摘要

集合 普通集合 List<String> list = Lists.newArrayList(); Set<String> set = Sets.newH

集合

普通集合


List<String> list = Lists.newArrayList();
Set<String> set = Sets.newHashSet();
Map<String, String> map = Maps.newHashMap();

Set 取交集、并集、差集


HashSet<Integer> setA = Sets.newHashSet(1, 2, 3, 4, 5);
HashSet<Integer> setB = Sets.newHashSet(4, 5, 6, 7, 8);
Sets.SetView<Integer> uNIOn = Sets.union(setA, setB);
System.out.println("union:" + union);
Sets.SetView<Integer> difference = Sets.difference(setA, setB);
System.out.println("difference:" + difference);
Sets.SetView<Integer> intersection = Sets.intersection(setA, setB);
System.out.println("intersection:" + intersection);

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> differenceMap = Maps.difference(mapA, mapB);
Map<String, MapDifference.ValueDifference<Integer>> entriesDiffering = differenceMap.entriesDiffering();
//左边差集
Map<String, Integer> entriesOnlyLeft = differenceMap.entriesOnlyOnLeft();
//右边差集
Map<String, Integer> entriesOnlyRight = differenceMap.entriesOnlyOnRight();
//交集
Map<String, Integer> entriesInCommon = differenceMap.entriesInCommon();
System.out.println(entriesDiffering);   // {b=(2, 20)}
System.out.println(entriesOnlyLeft);    // {a=1}
System.out.println(entriesOnlyRight);   // {d=4}
System.out.println(entriesInCommon);    // {c=3}

不可变集合(immutable)

不可变集合的特性有:

  • 多线程操作下,是线程安全的;
  • 所有不可变集合会比可变集合更有效的利用资源;
  • 中途不可改变。

如果你的需求是想创建一个一经初始化后就不能再被改变的集合那么它适合你,因为这些工具类根本就没给你提供修改的 api,这意味着你连犯错误的机会都没有。


ImmutableList<Integer> iList = ImmutableList.of(12,54,87);
ImmutableSet<Integer> iSet = ImmutableSet.of(354,54,764,354);
ImmutableMap<String, Integer> iMap = ImmutableMap.of("k1", 453, "k2", 534);

以上 Immutable 开头的相关集合类的 add、remove 方法都被声明为 deprecated。当你手误点到了这些方法发现是 deprecated 的时候你不会还想着使用吧。

注意:每个Guava immutable集合类的实现都拒绝 null 值。

有趣的集合

MultiSet: 无序+可重复

我们映像中的 Set 应该是无序的,元素不可重复的。MultiSet 颠覆了三观,因为它可以重复。

定义一个 MultiSet 并添加元素:


Multiset<Integer> set = HashMultiset.create();
set.add(3);
set.add(3);
set.add(4);
set.add(5);
set.add(4);

你还可以添加指定个数的同一个元素:


set.add(7, 3);

这表示你想添加 3 个 7。

打印出来的 MultiSet 也很有意思:


[3 x 2, 4 x 2, 5, 7 x 3]

2个3,2个4,一个5,3个7。

获取某个元素的个数:


int count = set.count(3);

这个工具类确实很有意思,帮我们实现了 Word count。

Multimap :key 可以重复的 map

这个 map 也很有意思。正常的 map 为了区分不同的 key,它倒好,直接给你来一样的 key 。


Multimap<String, String> map = LinkedHashMultimap.create();
map.put("key", "haha");
map.put("key", "haha1");
Collection<String> key = map.get("key");
System.out.println(key);

使用很简单,用一个 key 可以获取到该 key 对应的两个值,结果用 list 返回。恕我无知,我还没想到这个 map 能够使用的场景。

Multimap 提供了多种实现:

Multimap 实现 key 字段类型 value 字段类型
ArrayListMultimap HashMap ArrayList
HashMultimap HashMap HashSet
LinkedListMultimap LinkedHashMap LinkedList
LinkedHashMultimap LinkedHashMap LinkedHashSet
TreeMultimap TreeMap TreeSet
ImmutableListMultimap ImmutableMap ImmutableList
ImmutableSetMultimap ImmutableMap ImmutableSet

双向 Map

(Bidirectional Map) 键与值都不能重复

这个稍稍正常一点。如果 key 重复了则会覆盖 key ,如果 value 重复了则会报错。


public static void main(String[] args) {
  BiMap<String, String> biMap = HashBiMap.create();
  biMap.put("key", "haha");
  biMap.put("key", "haha1");
  biMap.put("key1", "haha");
  String value = biMap.get("key");
  System.out.println(value);
}

上面的示例中键 ”key“ 有两个,运行可以发现 get 的时候会用 ”haha1" 覆盖 ”haha“,另外 value 为 ”haha“ 也有两个,你会发现运行上面的代码不会报错,这是因为 ”key“ 对应的 value 已经被 "haha1" 覆盖了。否则是会报错。

双键 map - 超级实用

双键的 map ,我突然感觉我发现了新大陆。比如我有一个业务场景是:根据职位和部门将公司人员区分开来。key 可以用职位 + 部门组成一个字符串,那我们有了双键 map 之后就没这种烦恼。


public static void main(String[] args) {
  Table<String, String, List<Object>> tables = HasHBasedTable.create();
  tables.put("财务部", "总监", Lists.newArrayList());
  tables.put("财务部", "职员",Lists.newArrayList());
  tables.put("法务部", "助理",Lists.newArrayList());
  System.out.println(tables);
}

工具类

jdk里大家耳熟能详的是Collections 这个集合工具类, 提供了一些基础的集合处理转换功能, 但是实际使用里很多需求并不是简单的排序, 或者比较数值大小, 然后 Guava 在此基础上做了许多的改进优化, 可以说是 Guava 最为成熟/流行的模块之一。

  • 数组相关:Lists
  • 集合相关:Sets
  • map 相关:Maps

连接符(Joiner)和分隔符(Splitter)

Joiner 做为连接符的使用非常简单,下例是将 list 转为使用连接符连接的字符串:


List<Integer> list = Lists.newArrayList();
list.add(34);
list.add(64);
list.add(267);
list.add(865);
String result = Joiner.skipNulls().on("-").join(list);
System.out.println(result);
输出:34-64-267-865

将 map 转为自定义连接符连接的字符串:


Map<String, Integer> map = Maps.newHashMap();
map.put("key1", 45);
map.put("key2",234);
String result = Joiner.on(",").withKeyValueSeparator("=").join(map);
System.out.println(result);
输出:
key1=45,key2=234

分隔符 Splitter 的使用也很简单:


String str = "1-2-3-4-5-6";
List<String> list = Splitter.on("-").splitToList(str);
System.out.println(list);
输出:
[1, 2, 3, 4, 5, 6]

如果字符串中带有空格,还可以先去掉空格:


String str = "1-2-3-4-  5-  6   ";
List<String> list = Splitter.on("-").omitEmptyStrings().trimResults().splitToList(str);
System.out.println(list);

将 String 转为 map:


String str = "key1=54,key2=28";
Map<String,String> map = Splitter.on(",").withKeyValueSeparator("=").split(str);
System.out.println(map);
输出:
{key1=54, key2=28}

Comparator 的实现

Java 提供了 Comparator 可以用来对对象进行排序。Guava 提供了排序器 Ordering 类封装了很多实用的操作。

Ordering 提供了一些有用的方法:

  • natural() 对可排序类型做自然排序,如数字按大小,日期按先后排序
  • usingToString() 按对象的字符串形式做字典排序[lexicographical ordering]
  • from(Comparator) 把给定的Comparator转化为排序器
  • reverse() 获取语义相反的排序器
  • nullsFirst() 使用当前排序器,但额外把null值排到最前面。
  • nullsLast() 使用当前排序器,但额外把null值排到最后面。
  • compound(Comparator) 合成另一个比较器,以处理当前排序器中的相等情况。 lexicographical() 基于处理类型T的排序器,返回该类型的可迭代对象Iterable的排序器。
  • onResultOf(Function) 对集合中元素调用Function,再按返回值用当前排序器排序。

示例:


UserInfo build = UserInfo.builder().uid(234L).gender(1).build();
UserInfo build1 = UserInfo.builder().uid(4354L).gender(0).build();
Ordering<UserInfo> byOrdering = Ordering.natural().nullsFirst().onResultOf((Function<UserInfo, Comparable<Integer>>) input -> input.getGender());
System.out.println(byOrdering.compare(build1, build));

build 的 gender 大于 build1 的,所以返回 -1,反之返回 1。

统计中间代码运行时间

Stopwatch 类提供了时间统计的功能,相当于帮你封装了调用 System.currentTimeMillis() 的逻辑。


Stopwatch stopwatch = Stopwatch.createStarted();
try {
  //TODO 模拟业务逻辑
  Thread.sleep(2000L);
} catch (InterruptedException e) {
  e.printStackTrace();
}
long nanos = stopwatch.elapsed(TimeUnit.SECONDS);
System.out.println(nanos);

Guava Cache - 本地缓存组件

Guava Cache 在日常的使用中非常地频繁,甚至都没有意识到这是第三方提供的工具类而是把它当成了 JDK 自带的实现。


// LoadinGCache是Cache的缓存实现
LoadingCache<String, Object> cache = CacheBuilder.newBuilder()
  //设置缓存大小
  .maximumSize(1000)
  //设置到期时间
  .expireAfterWrite(10, TimeUnit.MINUTES)
  //设置缓存里的值两分钟刷新一次
  .refreshAfterWrite(2, TimeUnit.MINUTES)
  //开启缓存的统计功能
  .recordStats()
  //构建缓存
  .build(new CacheLoader<String, Object>() {
    //此处实现如果根据key找不到value需要去如何获取
    @Override
    public Object load(String s) throws Exception {
      return new Object();
    }
    //如果批量加载有比反复调用load更优的方法则重写这个方法
    @Override
    public Map<String, Object> loadAll(Iterable<? extends String> keys) throws Exception {
      return super.loadAll(keys);
    }
  });

设置本地缓存使用 CacheBuilder.newBuilder(),支持设置缓存大小,缓存过期时间,缓存刷新频率等等。如果你想统计缓存的命中率, Guava Cache 也提供了这种能力帮你汇总当前缓存是否有效。

同时缓存如果因为某种原因未自动刷新或者清除,Guava Cache 也支持用户手动调用 API 刷新或者清除缓存。


cache.invalidateAll();//清除所有缓存项
//清理的时机:在写操作时顺带做少量的维护工作,或者偶尔在读操作时做——如果写操作实在太少的话
//如果想自己维护则可以调用Cache.cleanUp();
cache.cleanUp();
//另外有时候需要缓存中的数据做出变化重载一次,这个过程可以异步执行
cache.refresh("key");

单机限流工具类 - RateLimiter

常用的限流算法有 漏桶算法、令牌桶算法。这两种算法各有侧重点:

  • 漏桶算法:漏桶的意思就像一个漏斗一样,水一滴一滴的滴下去,流出是匀速的。当访问量过大的时候这个漏斗就会积水。漏桶算法的实现依赖队列,一个处理器从队头依照固定频率取出数据进行处理。如果请求量过大导致队列堆满那么新来的请求就会被抛弃。漏桶一般按照固定的速率流出。
  • 令牌桶则是存放固定容量的令牌,按照固定速率从桶中取出令牌。初始给桶中添加固定容量令牌,当桶中令牌不够取出的时候则拒绝新的请求。令牌桶不限制取出令牌的速度,只要有令牌就能处理。所以令牌桶允许一定程度的突发,而漏桶主要目的是平滑流出。

RateLimiter 使用了令牌桶算法,提供两种限流的实现方案:

  • 平滑突发限流(SmoothBursty)
  • 平滑预热限流(SmoothWarmingUp)

实现平滑突发限流通过 RateLimiter 提供的静态方法来创建:


RateLimiter r = RateLimiter.create(5);
while (true) {
  System.out.println("get 1 tokens: " + r.acquire() + "s");
}
输出:
get 1 tokens: 0.0s
get 1 tokens: 0.197059s
get 1 tokens: 0.195338s
get 1 tokens: 0.196918s
get 1 tokens: 0.19955s
get 1 tokens: 0.199062s
get 1 tokens: 0.195589s
get 1 tokens: 0.195061s
......  

设置每秒放置的令牌数为 5 个,基本 0.2s 一次符合每秒 5 个的设置。保证每秒不超过 5 个达到了平滑输出的效果。

在没有请求使用令牌桶的时候,令牌会先创建好放在桶中,所以此时如果突然有突发流量进来,由于桶中有足够的令牌可以快速响应。RateLimiter 在没有足够令牌发放时采用滞后处理的方式,前一个请求获取令牌所需等待的时间由下一次请求来承受。

平滑预热限流并不会像平滑突发限流一样先将所有的令牌创建好,它启动后会有一段预热期,逐步将分发频率提升到配置的速率。

比如下面例子创建一个平均分发令牌速率为 2,预热期为 3 分钟。由于设置了预热时间是 3 秒,令牌桶一开始并不会 0.5 秒发一个令牌,而是形成一个平滑线性下降的坡度,频率越来越高,在 3 秒钟之内达到原本设置的频率,以后就以固定的频率输出。这种功能适合系统刚启动需要一点时间来“热身”的场景。


RateLimiter r = RateLimiter.create(2, 3, TimeUnit.SECONDS);
while (true) {
  System.out.println("get 1 tokens: " + r.acquire(1) + "s");
  System.out.println("get 1 tokens: " + r.acquire(1) + "s");
  System.out.println("end");
}
输出:
get 1 tokens: 0.0s
get 1 tokens: 1.33068s
end
get 1 tokens: 0.995792s
get 1 tokens: 0.662838s
end
get 1 tokens: 0.494775s
get 1 tokens: 0.497293s
end
get 1 tokens: 0.49966s
get 1 tokens: 0.49625s
end

从上面的输出看前面两次获取令牌都很耗时,往后就越来越趋于平稳。

今天给大家介绍的常用的 Guava 工具类就这些,不过 JDK8 开始 Java官方 API 也在完善,比如像字符串相关的功能 JDK也很强大。都是工具,哪个好用就用哪个。

到此这篇关于java的Guava工具包介绍的文章就到这了,更多相关Guava工具包内容请搜索编程网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持编程网!

--结束END--

本文标题: java的Guava工具包介绍

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

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

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

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

下载Word文档
猜你喜欢
  • java的Guava工具包介绍
    集合 普通集合 List<String> list = Lists.newArrayList(); Set<String> set = Sets.newH...
    99+
    2022-11-12
  • Linux的包管理工具介绍
     概述:     本章内容:软件的运行环境,软件包基础,rpm包管理,yum管理,定制yum仓库,编译安装一、软件运行环境  1.API:Appl...
    99+
    2022-10-18
  • Java工具集介绍12_09
    Java工具集介绍12_091)Java 6 for MacOSX版本发布如果你是一个Mac用户,现在就值得高兴了,开源社区刚刚解决了这个问题,把Java 6移植到苹果的系统中。2)UMLGraph新版本:UMLGraph 5.0UMLGr...
    99+
    2023-06-03
  • Java中GUI工具包AWT和Swing用法介绍
    java 中编写 GUI 有两中工具包,分别为 AWT、Swing。 Swing 是 AWT 的拓展,Swing 具有比 AWT 丰富的组件和方法。 AWT 和 Swing 都能跨平...
    99+
    2022-11-13
  • 基于Java的guava开源库工具类
    目录基于Java的guava开源库工具类1、guava的maven配置引入 2、LoadingCache 3、Multimap 和 MultiSet4、BiMap5、Tab...
    99+
    2022-11-12
  • 基于Docker封装的开发包工具介绍
    本篇内容介绍了“基于Docker封装的开发包工具介绍”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!基于 Docker1.12+ (Docke...
    99+
    2023-06-04
  • Linux网络抓包工具tcpdump的详细介绍
    这篇文章主要介绍“Linux网络抓包工具tcpdump的详细介绍”,在日常操作中,相信很多人在Linux网络抓包工具tcpdump的详细介绍问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Linux网络抓包工具...
    99+
    2023-06-13
  • Android aapt自动打包工具详细介绍
    Android aapt自动打包工具 概念 在Android.mk中有LOCAL_AAPT_FLAGS配置项,在gradle中也有aaptOptions,那么aapt到底是干什...
    99+
    2022-06-06
    工具 aapt Android
  • oracle管理工具的介绍
    oracle管理工具的介绍(1)===================================================================sql*plus是oracle自带的工具...
    99+
    2022-10-18
  • pt(Percona Toolkit)工具介绍
           pt(Percona Toolkit)工具介绍一.介绍1.找出重复的索引和外键    pt-duplicate-key-c...
    99+
    2022-10-18
  • MySQL 5.7 mysqldumpslow工具介绍
    mysqldumpslow工具可以用来归纳总结慢查询日志的信息。 MySQL慢查询日志包含执行时间较长的查询信息。mysqldumpslow工具可以解析MySQL慢查询日志文件并打印出他们内容的汇总信息...
    99+
    2022-10-18
  • mydumper工具使用介绍
    背景:mysqldump mysqlpump mydumper 三种逻辑备份工具的比较 mysqlpump的介绍(转):http://www.cnblogs.com/zhoujinyi/p/5684903...
    99+
    2022-10-18
  • AndroidNativefdsan检测工具介绍
    目录正文一个fd由生到死的所有者tag组成tag的创建和检验过程正文 本文分析基于Android T(13) fdsan,全名为file descriptor sanitizer,...
    99+
    2023-02-10
    Android Native fdsan检测工具 Android Native
  • Jar包常见的反编译工具介绍与使用
    反编译JAR能干什么: 排查问题、分析商业软件代码逻辑,学习优秀的源码思路。 反编译工具介绍 JD-GUI 下载地址:http://java-decompiler.github.io/ 点评:支...
    99+
    2023-10-22
    Java 反编译 Jar JD-GUI
  • mysql备份的工具mysqldump介绍
    下面讲讲关于mysql备份的工具mysqldump,文字的奥妙在于贴近主题相关。所以,闲话就不谈了,我们直接看下文吧,相信看完mysql备份的工具mysqldump介绍这篇文章你一定会有所受益。节点11、节...
    99+
    2022-10-18
  • MySQL中的相关工具介绍
    这篇文章主要介绍“MySQL中的相关工具介绍”,在日常操作中,相信很多人在MySQL中的相关工具介绍问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”MySQL中的相关工具介绍”...
    99+
    2022-10-18
  • java guava主要功能介绍及使用心得总结
    目录1. 前言2. Guava主要功能介绍2.1 集合操作2.2 缓存2.3 字符串处理2.4 函数式编程2.5 其他实用工具3. 结论1. 前言 Guava是一个由Google开发...
    99+
    2023-05-16
    java guava使用 java guava
  • Java两大工具库Commons和Guava如何使用
    本文小编为大家详细介绍“Java两大工具库Commons和Guava如何使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java两大工具库Commons和Guava如何使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习...
    99+
    2023-07-05
  • python实用小工具介绍
    一、秒级启动一个HTTP下载服务器在实际工作中,时不时会有这样的一个需求:将文件传给其他同事。将文件传给同事本身并不是一个很繁琐的工作,现在的聊天工具一般都支持文件传输。但是,如果需要传送的文件较多,那么,操作起来就会比较麻烦。此外,如果文...
    99+
    2023-01-31
    小工具 python
  • BeanUtils工具类的介绍和使用
    BeanUtils是Apache Commons BeanUtils库中的一个工具类,用于简化JavaBean之间的属性复制。它提供...
    99+
    2023-09-21
    BeanUtils
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作