Maven依赖
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.1-jre</version>
</dependency>
对基本类型的扩展
Guava对JDK提供的原生类型操作进行了扩展,使得功能更加强大。
// 快速完成到集合的转换
List<Integer> list = Ints.asList(1, 2, 6, 20, 7);
// 快速按分隔符连接
String join = Ints.join(",", 1, 2, 6, 20, 7);
// 数组快速合并
int[] newIntArray = Ints.concat(new int[]{1,2}, new int[]{4,5,6});
// 最大
int max = Ints.max(newIntArray);
// 最小
int min = Ints.min(newIntArray);
boolean contains = Ints.contains(newIntArray, 1);
// 集合到数组的转换
int[] array = Ints.toArray(list);
Guava提供了Bytes/Shorts/Ints/Iongs/Floats/Doubles/Chars/Booleans这些基本数据类型的扩展支持,只有你想不到的,没有它没有的!
Preconditions
在guava中,对于null的处理手段是快速失败。
Preconditions:前提条件
String name = "";
Preconditions.checkNotNull(name, "name is not null");
Integer age = 30;
Preconditions.checkArgument(age>=18, "your age is under 18");
Cache
对于大多数互联网项目而言,缓存的重要性,不言而喻!
如果我们的应用系统,并不想使用一些第三方缓存组件(如redis),我们仅仅想在本地有一个功能足够强大的缓存,很可惜JDK提供的那些SET/MAP还不行!
// 缓存的实现
private static final CacheLoader<Long, String> cacheLoader = new CacheLoader<Long, String>() {
@Override
public String load(Long key) throws Exception {
// TODO 从数据库加载数据
System.out.println("从数据库加载数据");
return key + ":value";
}
};
// 定义缓存的策略
private static final LoadingCache<Long, String> loadingCache = CacheBuilder.newBuilder()
.expireAfterAccess(2, TimeUnit.SECONDS) // 设置在2秒内未访问则过期
.expireAfterWrite(2, TimeUnit.SECONDS) // 设置缓存在写入2秒后失效
.refreshAfterWrite(3, TimeUnit.SECONDS) // 设置缓存在写入3秒后,通过CacheLoader的load方法进行刷新
.maximumSize(100L) // 设置缓存数量上限为100
.build(cacheLoader);
public static void main(String[] args) throws Exception {
//loadingCache.put(1L, "James");
System.out.println(loadingCache.get(1L));
Thread.sleep(5000L);
System.out.println(loadingCache.get(1L));
}
首先,这是一个本地缓存,guava提供的cache是一个简洁、高效,易于维护的。为什么这么说呢?因为并没有一个单独的线程用于刷新 OR 清理cache,对于cache的操作,都是通过访问/读写带来的,也就是说在读写中完成缓存的刷新操作!
其次,我们看到了,我们非常通俗的告诉cache,我们的缓存策略是什么,SO EASY!在如此简单的背后,是guava帮助我们做了很多事情,比如线程安全。
加强异步回调
JDK中提供了Future/FutureTask/Callable来对异步回调进行支持,但是还是看上去挺复杂的,能不能更加简单呢?比如注册一个监听回调。
ExecutorService es = Executors.newFixedThreadPool(3);
ListeningExecutorService listeningExecutorService = MoreExecutors.listeningDecorator(es);
ListenableFuture<?> listenableFuture = listeningExecutorService.submit(() -> {
if(new Random().nextInt(3) == 2){
throw new NullPointerException();
}
return 1;
});
FutureCallback<Integer> futureCallback = new FutureCallback<Integer>() {
@Override
public void onSuccess(@Nullable Integer o) {
System.out.println("------" + o);
}
@Override
public void onFailure(Throwable throwable) {
System.out.println("------" + throwable.getMessage());
}
};
Futures.addCallback(listenableFuture,futureCallback);
我们可以通过guava对JDK提供的线程池进行装饰,让其具有异步回调监听功能,然后在设置监听器即可!
计算中间代码的运行时间
Stopwatch stopwatch = Stopwatch.createStarted();
for(int i=0; i<100000; i++){
// do some thing
}
long nanos = stopwatch.elapsed(TimeUnit.MILLISECONDS);
System.out.println(nanos);
TimeUnit 可以指定时间输出精确到多少时间。
参考
为什么推荐 Java 程序员使用 Google Guava 编程
Google guava工具类的介绍和使用
Guava 易百教程