Guava
Guava是一个Google开源的Java核心库,它提供了许多实用的工具和辅助类,使Java开发更加简洁、高效、可靠。目前和hutool
一起,是业界常用的工具类库。shigen
也比较喜欢使用,在这里列举一下常用的工具类库和使用的案例。
参考:
pom依赖
XML
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>30.1.1-jre</version>
</dependency>
Map
Table-双键map
Table 接口可以看作是一个类似于矩阵的数据结构,它包含两个键:行键和列键。它的主要特点是可以通过两个键来定位和访问值, 它的类型:Table<R,C,V>
基础的api
行列的转制
Java
public static <R, C, V> Table<C, R, V> transpose(Table<R, C, V> table) {
return (Table)(table instanceof Tables.TransposeTable ? ((Tables.TransposeTable)table).original : new Tables.TransposeTable(table));
}
转换成嵌套的map
Java
Map<String, Map<String, Integer>> rowMap = table.rowMap();
Map<String, Map<String, Integer>> columnMap = table.columnMap();
BiMap-双向map
根据value快速找到key,所以要求key 和value都是唯一的
- 用
inverse
方法反转了原来BiMap
的键值映射,但是这个反转后的BiMap
并不是一个新的对象,它实现了一种视图的关联,所以对反转后的BiMap
执行的所有操作会作用于原先的BiMap
上。 - 继承hashMap,key、value都不能重复的
MultiMap-多值map
一个键映射到多个值上,底层是Map<String, List>
创建和转换
Java
Multimap<String, String> multiMap = ArrayListMultimap.create();
multiMap.putAll("name", Arrays.asList("shigen", "aaa", "bbb"));
Collection<String> names = multiMap.get("name");
Map<String, Collection<String>> stringCollectionMap = multiMap.asMap();
RangeMap-范围map
RangeMap
描述了一种从区间到特定值的映射关系,让我们能够以更为优雅的方法来书写代码
分数段判断案例
'com.google.common.collect.RangeMap' is marked unstable with @Beta
shigen
觉得这个很好用,为我们省略了很多根据区间判断的if-else代码
Java
RangeMap<Integer, String> rangeMap = TreeRangeMap.create();
rangeMap.put(Range.closedOpen(0,60),"fail");
rangeMap.put(Range.closed(60,90),"satisfactory");
rangeMap.put(Range.openClosed(90,100),"excellent");
System.out.println(rangeMap.get(59));
System.out.println(rangeMap.get(60));
System.out.println(rangeMap.get(90));
System.out.println(rangeMap.get(91));
ClassToInstanceMap-实例Map
它的键是Class
,而值是这个Class
对应的实例对象(Map<Class, List<Object>
)。取出对象时省去了强制类型转换,避免手动类型转换失误。
适合缓存对象,但是又不想做复杂的校验
Java
MutableClassToInstanceMap<List> listMutableClassToInstanceMap = MutableClassToInstanceMap.create();
ArrayList<String> strings = new ArrayList<>();
strings.add("1111");
listMutableClassToInstanceMap.putInstance(ArrayList.class, strings);
ArrayList instance = listMutableClassToInstanceMap.getInstance(ArrayList.class);
// true
System.out.println(strings == instance);
Strings
isNullOrEmpty(String string)
:判断字符串是否为空或null。padEnd(String string, int minLength, char padChar)
:在字符串末尾填充指定字符,直到字符串达到指定长度。padStart(String string, int minLength, char padChar)
:在字符串开头填充指定字符,直到字符串达到指定长度。repeat(String string, int count)
:重复指定字符串指定次数。commonPrefix(CharSequence a, CharSequence b)
:获取两个字符串的最长公共前缀。commonSuffix(CharSequence a, CharSequence b)
:获取两个字符串的最长公共后缀。
这一块
shigen
还是习惯了使用hutool
的strUtil
,很符合我的代码编程习惯。
Collections
ImmutableList
不可变集合是Guava的一个重要特性,它可以确保集合不被修改,从而避免并发访问的问题
Java
List<String> list = Lists.newArrayList("a", "b", "c");
ImmutableList<String> immutableList = ImmutableList.copyOf(list);
Iterables
获得元素的API
获得符合条件的元素
转换集合类型
条件检查(Preconditions)
Preconditions是Guava提供的一组前置条件检查工具,它提供了一些检查参数是否符合预期的方法。
shigen
觉得这个和assert
很相像。
以下是Preconditions的主要方法:
checkArgument(boolean expression, String errorMessageTemplate, Object... errorMessageArgs)
:检查参数是否符合预期,并抛出IllegalArgumentException异常,可以包含错误信息模板和占位符。checkNotNull(T reference, String errorMessageTemplate, Object... errorMessageArgs)
:检查参数是否为null,并抛出NullPointerException异常,可以包含错误信息模板和占位符。checkState(boolean expression, String errorMessageTemplate, Object... errorMessageArgs)
:检查对象状态是否符合预期,并抛出IllegalStateException异常,可以包含错误信息模板和占位符。checkElementIndex(int index, int size, String errorMessageTemplate, Object... errorMessageArgs)
:检查下标是否在集合的范围内,并抛出IndexOutOfBoundsException异常,可以包含错误信息模板和占位符。checkPositionIndex(int index, int size, String errorMessageTemplate, Object... errorMessageArgs)
:检查下标是否在集合的范围内,可以等于集合的大小,并抛出IndexOutOfBoundsException异常,可以包含错误信息模板和占位符。checkPositionIndexes(int start, int end, int size)
:检查开始下标和结束下标是否在集合的范围内,并抛出IndexOutOfBoundsException异常。
Java
public class PreconditionsDemo {
public static void main(String[] args) {
// 检查参数是否符合预期,并抛出IllegalArgumentException异常,可以包含错误信息模板和占位符
String str1 = "abc";
Preconditions.checkArgument(str1.length() < 3, "字符串长度必须小于3");
// 检查参数是否为null,并抛出NullPointerException异常,可以包含错误信息模板和占位符
String str2 = null;
Preconditions.checkNotNull(str2, "字符串不能为空");
// 检查对象状态是否符合预期,并抛出IllegalStateException异常,可以包含错误信息模板和占位符
boolean flag1 = false;
Preconditions.checkState(flag1, "状态不正确");
// 检查下标是否在集合的范围内,并抛出IndexOutOfBoundsException异常,可以包含错误信息模板和占位符
List<Integer> list1 = Lists.newArrayList(1, 2, 3, 4, 5);
Preconditions.checkElementIndex(6, list1.size(), "下标越界");
// 检查下标是否在集合的范围内,可以等于集合的大小,并抛出IndexOutOfBoundsException异常,可以包含错误信息模板和占位符
List<Integer> list2 = Lists.newArrayList(1, 2, 3, 4, 5);
Preconditions.checkPositionIndex(5, list2.size(), "下标越界");
// 检查开始下标和结束下标是否在集合的范围内,并抛出IndexOutOfBoundsException异常
List<Integer> list3 = Lists.newArrayList(1, 2, 3, 4, 5);
Preconditions.checkPositionIndexes(2, 6, list3.size());
// 可以在错误信息中使用占位符
int value1 = 101;
Preconditions.checkArgument(value1 <= 100, "值必须小于等于 %s", 100);
// 可以使用Supplier来避免计算开销
int value2 = 101;
Preconditions.checkArgument(value2 <= 100, () -> "值必须小于等于 " + 100);
}
cacheBuilder
Cache是Guava提供的一个缓存工具类,它可以帮助我们在内存中缓存数据。
- 缓存加载:指定缓存加载机制。可以通过传递一个 CacheLoader 对象来定义如何加载缓存中不存在的数据。CacheLoader 是一个抽象类,需要实现 load 方法,用于根据键加载对应的值。
- 缓存大小限制:设置缓存的最大容量,当缓存超过设定的容量时,可以通过一些策略(比如使用 LRU 或 FIFO)来自动淘汰一些不常用的缓存项。可以使用 maximumSize 方法设置缓存的最大容量。
- 过期时间:为缓存项设置过期时间。可以通过 expireAfterWrite 或 expireAfterAccess 方法设置缓存项的写入或访问后的过期时间。
- 弱引用键或值:CacheBuilder 提供了一些选项,可以使用弱引用持有缓存的键或值。当没有其他地方引用某个键或值时,缓存会自动将其从内存中移除,以避免内存泄漏。
- 统计信息:CacheBuilder 提供了一些统计信息,包括缓存的命中率、加载次数、加载成功率等。可以通过调用 recordStats 方法开启统计信息的收集。
Java
@SneakyThrows
private static void testCache() {
// 创建一个缓存实例
Cache<String, String> cache = CacheBuilder.newBuilder()
// 最大容量为100个缓存项
.maximumSize(100)
// 10分钟后过期
.expireAfterWrite(10, TimeUnit.MINUTES)
.build();
// 向缓存中存入数据
cache.put("key1", "value1");
cache.put("key2", "value2");
// 从缓存中获取数据
String value1 = cache.getIfPresent("key1");
// 输出: Value1: value1
System.out.println("Value1: " + value1);
// 存中存在,则返回对应的值;如果缓存中不存在,则使用提供的函数加载新的值,并将其添加到缓存中
String value3 = cache.get("key3", () -> "value3");
// 输出: Value3: value3
System.out.println("Value3: " + value3);
// 获取缓存的统计信息
CacheStats stats = cache.stats();
// 输出: Hit Rate: 1.0
System.out.println("Hit Rate: " + stats.hitRate());
}
以上就是这些常用的使用场景了。也欢迎伙伴们交流一下常用的工具库的方法。
与shigen
一起,每天不一样!