高质量的GoogleGuava库
GoogleGuava 辅助库是java1.6及以上的类库集合的扩展项目
里面包含大量高质量的 API 可以使你的Java代码更加优雅,更加简洁,让你工作更加轻松愉悦
本文章主要向大家介绍guava库的基本使用和小编抽取的一些不错操作
先上jar包下载地址
- https://www.jb51.net/softs/54...
安装难度并不大 所以不做太多介绍
ps:虽然不是官网 但是很稳定哦
Guava 流畅的基本工具 Basic utilities
-
Optional 使用和避免null
Optional小编觉得更重要的不是代码本身 而是给程序员一种神经提示 进而带动程序员积极思考引用缺失的问题
- 由于基本工具所要举得例子不是很多 在此小编直接贴入网址在这里会有更好的对Guava基本工具的解析
- https://wiki.jikexueyuan.com/...
Guava 对集合的强力扩展 collect
Guava对已有集合的能力增强
-
可变集合的创建 Lists、Sets、Maps、Collections2
针对jdk中已存在的集合建立的工具类
//jdk中的普通方式
Map mp=new HashMap<>();
//Guava中的方式
List list = Lists.newArrayList();
Set set = Sets.newHashSet();
Map map = Maps.newHashMap();
//当然也可以利用静态导入的方式让代码更简单
List list = newArrayList();
//关于Eclipse中设置静态导入在文章结尾会跟大家介绍
-
不可变集合的创建 ImmutableCollection、ImmutableMap
在多线程操作下,是线程安全的
比可变集合更有效的利用资源
中途不能添加或更改元素
通常我们需要一个测试集合的时候便可以用到此接口
ps: jdk9也已经实现类似方法
var list=ImmutableList.of("1","2","3","4");
var set=ImmutableSet.of("a", "b", "c", "d");
var map=ImmutableMap.of("key1", "value1", "key2", "value2");
//jdk9中的创建不可变集合的方式也很简单
List.of("Hello", "World");
Set.of("Hello", "World");
Map.of("Hello", 1, "World", 2);
- 更智能的ImmutableXXX.copyOf
会尝试在安全的时候避免做拷贝——实际的实现细节不详,但通常来说是很智能的 - 关于不可变并且有序集合ImmutableSortedxxx
var set=ImmutableSortedSet.of(2,1,3,2,5,4);
out.println(set);
//1,2,3,4,5 排序并且排重
Guava中新增的牛X集合
-
Multiset
可以用两种方式看待 Multiset:
- 没有元素顺序限制的 ArrayList
- Map
,键为元素,值为计数
Multiset 没有继承Set接口 不等于Set
常用 Multiset 接口的实现类有:- HashMultiset: 元素存放于 HashMap
- LinkedHashMultiset: 元素存放于 LinkedHashMap,即元素排列顺序由第一次放入的顺序决定
- TreeMultiset:元素被排序存放于TreeMap
- EnumMultiset: 元素必须是 enum 类型
- ImmutableMultiset: 不可修改的 Mutiset
Multiset接口定义的抽象方法主要有:
- add(E element) :向其中添加单个元素
- add(E element,int occurrences) : 向其中添加指定个数的元素
- count(Object element) : 返回给定参数元素的个数
- remove(E element) : 移除一个元素,其count值 会响应减少
- remove(E element,int occurrences): 移除相应个数的元素
- elementSet() : 将不同的元素放入一个Set中
- entrySet(): 类似与Map.entrySet 返回Set
。包含的Entry支持使用getElement()和getCount() - setCount(E element ,int count): 设定某一个元素的重复次数
- setCount(E element,int oldCount,int newCount): 将符合原有重复个数的元素修改为新的重复次数
- retainAll(Collection c) : 保留出现在给定集合参数的所有的元素
- removeAll(Collectionc) : 去除出现在给定集合参数的所有的元素
HashMultiset multiSet = HashMultiset.create();
multiSet.add("1");
multiSet.add("1");
multiSet.add("2");
multiSet.add("3", 3);
out.println(multiSet.count("1")+"次");
//2次
out.println(multiSet);
//[1 x 2, 2, 3 x 3]
out.println("元素个数"+multiSet.size());
//元素个数6
- 如果看过我Stream介绍那篇文章的小伙伴也会想到用MultiSet来计算字符串中的元素出现个数 哈哈哈
//题目是 求出字符串中的元素出现的个数
利用MultiSet可想而知一定很简单 我们只要处理一下重复元素就好
那么我们便可用Stream的知识简单的处理重复元素:
Multiset
-
MultiMap
ps:不是Map
可以用两种方式思考 Multimap 的概念:- ”键-单个值映射”的集合:
a -> 1 a -> 2 a ->4 b -> 3 c -> 5 -
或者”键-值集合映射”的映射:
a -> [1, 2, 4] b -> 3 c -> 5常用实现类:
在大多数要使用 Map的地方,你都可以使用它们:
- ”键-单个值映射”的集合:
实现类 | 键行为对应的集合 | 值行为对应的集合 |
---|---|---|
ArrayListMultimap | HashMap | ArrayList |
HashMultimap | HashMap | HashSet |
LinkedListMultimap | LinkedHashMap | LinkedList |
LinkedHashMultimap | LinkedHashMap | LinkedHashMap |
TreeMultimap | TreeMap | TreeSet |
ImmutableSetMultimap | ImmutableMap | ImmutableSet |
List list = newArrayList();
list.add(4);
list.add(5);
list.add(6);
ListMultimap Multimap =ArrayListMultimap.create();
Multimap.put("1",1);
Multimap.put("1",2);
Multimap.put("1",3);
Multimap.putAll("2",list);
out.println(Multimap);
//{1=[1, 2, 3], 2=[4, 5, 6]}
-
BiMap 键值双向映射的map
- 可以用 inverse()反转 BiMap
的键值映射 - 保证值是唯一的,因此 values()返回 Set 而不是普通的 Collection
- 可以用 inverse()反转 BiMap
键-值实现 | 值-键实现 | 对应的BiMap实现 |
---|---|---|
HashMap | HashMap | HashBiMap |
ImmutableMap | ImmutableMap | ImmutableBiMap |
EnumMap | EnumMap | EnumBiMap |
EnumMap | HashMap | EnumHashBiMap |
BiMap biMap = HashBiMap.create();
biMap.put(1, "1");
biMap.put(4, "2");
biMap.put(3, "3");
//添加已有的值将新键覆盖旧键 forcePut
biMap.forcePut(2, "2");
out.println(biMap);//{1=1, 3=3, 2=2}
//将键值切换映射 inverse
var biMap2 = bimap.inverse();
out.println(biMap2.get("1"));//1
-
Table 多键检索的Map
- 它有两个支持所有类型的键:”行”和”列”。
- Table 提供多种视图,以便从各种角度使用它
常用实现类:
- HashBasedTable:本质上用 HashMap
>实现; - TreeBasedTable:本质上用 TreeMap
>实现; - ImmutableTable:本质上用 ImmutableMap
>实现;注:ImmutableTable 对稀疏或密集的数据集都有优化。 - ArrayTable:要求在构造时就指定行和列的大小,本质上由一个二维数组实现,以提升访问速度和密集 Table 的内存利用率。ArrayTable 与其他 Table 的工作原理有点不同,请参见 Javadoc 了解详情。
Table table = HashBasedTable.create();
table.put(1, "Asen", "百万");
table.put(1, "Bsen", "百万");
table.put(2,"Bsen","千万");
//双键查值
out.println(table.get(2, "Bsen"));
//行视图
out.println(table.row(1));
{Asen=百万, Bsen=百万}
//列视图
out.println(table.column("Bsen"));
{1=百万, 2=千万}
Guava对字符串的处理
小编这里额外说明一下:关于对字符串的处理小编觉得Guava是最棒的 综合性能更是没话说 下面各位慢慢欣赏
Joiner 连接器
- join 拼接集合中的元素
String join = Joiner.on("-_-").join(List.of("1", "2","3","4"));
//比stream先进的是 此方法可以支持任意类型 stream针对字符串之外还要先进行处理
String join2 = Joiner.on("-_-").join(List.of(5,6,7,8));
out.println(join);
//1-_-2-_-3-_-4
out.println(join2);
//5-_-6-_-7-_-8
- skipNullls 过滤null
String join3 = Joiner.on("~_~")
.skipNulls()
.join("1",null,"2","3");
out.println(join3);//1~_~2~_~3
- useForNull 替换null
String join4 = Joiner.on("~_~")
.useForNull("空")
.join("1",null,"2","3");
out.println(join4);//1~_~空~_~2~_~3
- withKeyValueSeparator 拼接Map中元素
//此时的字符串拼接则将Map中一个键值对看为一个整体 进行拼接
String join5 = Joiner.on("~_~")
.withKeyValueSeparator("值:")
.join(Map.of(1,10,2,20));
out.println(join5);//1值:10~_~2值:20
Splitter 字符分割
- split、splitToList 根据指定字符分割字符串,并转集合
Iterable split = Splitter.on(";")
.split("12;34;56;7");
split.forEach(out::println);
//12 34 56 7
// ps: 如果找不到指定字符则返回原字符串
- trimResults 将指定charmatcher转空串
List splitToList = Splitter.on(";")
.trimResults(CharMatcher.anyOf("a"))
.splitToList("aa;b");
// [, b]
- limit 指定分割个数
List list=Splitter.on(";")
.limit(2)
.splitToList("a;b;c");
//a b;c
List list=Splitter.on(";")
.limit(3)
.splitToList("a;b;c");
//a b c
- withKeyValueSeparator 转为Map
Map split3 = Splitter.on(";")
.withKeyValueSeparator("-")
.split("a-10;b-20");
split3.forEach((k,v)->out.println(k+"="+v));
//a=10 b=20
-
CharMatcher 字符匹配器
根据要求获取匹配器类型:
ANY: 匹配任何字符
ASCII: 匹配是否是ASCII字符
BREAKING_WHITESPACE: 匹配所有可换行的空白字符(不包括非换行空白字符,例如"\u00a0")
DIGIT: 匹配ASCII数字
INVISIBLE: 匹配所有看不见的字符
JAVA_DIGIT: 匹配UNICODE数字, 使用 Character.isDigit() 实现
JAVA_ISO_CONTROL: 匹配ISO控制字符, 使用 Charater.isISOControl() 实现
JAVA_LETTER: 匹配字母, 使用 Charater.isLetter() 实现
JAVA_LETTER_OR_DIGET: 匹配数字或字母
JAVA_LOWER_CASE: 匹配小写
JAVA_UPPER_CASE: 匹配大写
NONE: 不匹配所有字符
SINGLE_WIDTH: 匹配单字宽字符, 如中文字就是双字宽
WHITESPACE: 匹配所有空白字符
anyOf(CharSequence): 枚举匹配字符 如anyOf("aeiou")匹配小写英语元音
is(char): 给定单一字符匹配
inRange(char,char): 给定字符范围匹配 如inRange('a','z')
对获取到的匹配器进行处理:
collapseFrom(CharSequence, char) 把每组连续的字符替换为指定字符
matchesAllOf(CharSequence) 测试是否字符序列中的所有字符都匹配。
removeFrom(CharSequence) 从字符序列中移除所有匹配字符。
retainFrom(CharSequence) 在字符序列中保留匹配字符,移除其他字符。
trimFrom(CharSequence) 移除字符序列的前导匹配字符和尾部匹配字符。
replaceFrom(CharSequence, CharSequence) 用特定字符序列替代匹配字符。
更多方法还请参考: https://www.cnblogs.com/amei0...
//两个简单的栗子:
//求出字符串中英文字母的个数
var string="ab2dA-+=wq1c390";
var vstr=CharMatcher.JAVA_LETTER.retainFrom(string);
out.println(vstr);//abdAwqc
//过滤掉字符串中的数字
var string="12345hello90word";
var vint=CharMatcher.inRange('0', '9').removeFrom(string);
out.println(vstr);//helloword
//将字符串中任意长度空格用指定字符代替
String rs = CharMatcher
.whitespace()
.collapseFrom("42d3 gfsdg4f afdasf dasf3f ",'、');
- 当然了 这只是Guava的一小部分 更多精彩内容还请参考以下网址:
http://ifeve.com/google-guava/
https://wiki.jikexueyuan.com/...
关于Eclipse 静态导包问题
静态导包显然能让代码显得更简洁干练
下面具体说明EclipseMyEclipse如何设置指定静态导包