高质量的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<String,String> mp=new HashMap<>();
//Guava中的方式
List<String> list = Lists.newArrayList();
Set<String> set = Sets.newHashSet();
Map<String, String> map = Maps.newHashMap();
//当然也可以利用静态导入的方式让代码更简单
List<String> 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<E, Integer>,键为元素,值为计数
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<Multiset.Entry>。包含的Entry支持使用getElement()和getCount()
- setCount(E element ,int count): 设定某一个元素的重复次数
- setCount(E element,int oldCount,int newCount): 将符合原有重复个数的元素修改为新的重复次数
- retainAll(Collection c) : 保留出现在给定集合参数的所有的元素
- removeAll(Collectionc) : 去除出现在给定集合参数的所有的元素
HashMultiset<String> 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<Object> create = HashMultiset.create();
//依旧我们不给出字符串到集合的转换 大家总要消化下新知识嘛
create.addAll(List.of("1", "2", "1","q","b","1","z","z"));
利用Stream进行遍历 即排除了重复元素 又能正确的遍历结果 不伤害原集合
create.stream()
.distinct().sorted()
.forEach((s)->out.println(s+"出现次数"+create.count(s)));
//1出现次数3
//2出现次数1
//b出现次数1
//q出现次数1
//z出现次数2
ps 千万不要过于满足 应为我们还有更好的办法
-
MultiMap
ps:不是Map
可以用两种方式思考 Multimap 的概念:- ”键-单个值映射”的集合:
a -> 1 a -> 2 a ->4 b -> 3 c -> 5 -
或者”键-值集合映射”的映射:
a -> [1, 2, 4] b -> 3 c -> 5常用实现类:
在大多数要使用 Map<K, Collection>的地方,你都可以使用它们:
- ”键-单个值映射”的集合:
实现类 | 键行为对应的集合 | 值行为对应的集合 |
---|---|---|
ArrayListMultimap | HashMap | ArrayList |
HashMultimap | HashMap | HashSet |
LinkedListMultimap | LinkedHashMap | LinkedList |
LinkedHashMultimap | LinkedHashMap | LinkedHashMap |
TreeMultimap | TreeMap | TreeSet |
ImmutableSetMultimap | ImmutableMap | ImmutableSet |
List<Integer> list = newArrayList();
list.add(4);
list.add(5);
list.add(6);
ListMultimap<String,Integer> 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<K, V>的键值映射
- 保证值是唯一的,因此 values()返回 Set 而不是普通的 Collection
键-值实现 | 值-键实现 | 对应的BiMap实现 |
---|---|---|
HashMap | HashMap | HashBiMap |
ImmutableMap | ImmutableMap | ImmutableBiMap |
EnumMap | EnumMap | EnumBiMap |
EnumMap | HashMap | EnumHashBiMap |
BiMap<Integer,String> 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<R, HashMap<C, V>>实现;
- TreeBasedTable:本质上用 TreeMap<R, TreeMap<C,V>>实现;
- ImmutableTable:本质上用 ImmutableMap<R, ImmutableMap<C, V>>实现;注:ImmutableTable 对稀疏或密集的数据集都有优化。
- ArrayTable:要求在构造时就指定行和列的大小,本质上由一个二维数组实现,以提升访问速度和密集 Table 的内存利用率。ArrayTable 与其他 Table 的工作原理有点不同,请参见 Javadoc 了解详情。
Table<Integer,String,String> 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<String> split = Splitter.on(";")
.split("12;34;56;7");
split.forEach(out::println);
//12 34 56 7
// ps: 如果找不到指定字符则返回原字符串
- trimResults 将指定charmatcher转空串
List<String> splitToList = Splitter.on(";")
.trimResults(CharMatcher.anyOf("a"))
.splitToList("aa;b");
// [, b]
- limit 指定分割个数
List<String> list=Splitter.on(";")
.limit(2)
.splitToList("a;b;c");
//a b;c
List<String> list=Splitter.on(";")
.limit(3)
.splitToList("a;b;c");
//a b c
- withKeyValueSeparator 转为Map
Map<String, String> 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如何设置指定静态导包
- 确认开启静态导入选项 Window->Preferences->Java->Editor->Content Assist页面选中Use static imports
- 新键默认静态导入字段 Window->Preferences->Java->Editor->Content Assist->Favorites
- 使用方法:
快捷键导入还是不会导入静态字段的 这时候我们要手动敲出比如out 然后ALT+/ 提示选项第一个就是自动补全加默认静态导包了
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。