Guava定义
Guava是Google的一个开源Java框架,包含许多 Google 内部 Java 项目依赖的核心类,包括:从集合类型、不可变集合、图结构处理、并发工具、I/O、哈希、缓存等等各个方面的工具。
Guava作用
Guava是对Java API的补充,对Java开发中常用功能进行更优雅的实现,Guava库经过高度的优化,使得编码更加轻松,代码容易理解。
Guava类库
Guava这个库的常用改进方法,主要针对以下几类:
com.google.common.annotations:普通注解类型。 com.google.common.base:基本工具类库和接口。 com.google.common.cache:缓存工具包,非常简单易用且功能强大的JVM内缓存。 com.google.common.collect:带泛型的集合接口扩展和实现,以及工具类,这里你会发现很多好玩的集合。 com.google.common.eventbus:发布订阅风格的事件总线。 com.google.common.hash: 哈希工具包。 com.google.common.io:I/O工具包。 com.google.common.math:原始算术类型和超大数的运算工具包。 com.google.common.net:网络工具包。 com.google.common.primitives:八种原始类型和无符号类型的静态工具包。 com.google.common.reflect:反射工具包。 com.google.common.util.concurrent:多线程工具包。
- 集合;
- 缓存;
- 原生类型支持 ;
- 并发库;
- 通用注解;
- 字符串处理;
- I/O处理等;
Guava使用
1.引入Guava依赖
<!-- https://mvnrepository.com/artifact/com.google.guava/guava --> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>31.1-jre</version> </dependency>
2.集合工具类
// 创建一个 ArrayList 集合 List<String> list1 = Lists.newArrayList(); // 创建一个ArrayList,可以传不定长参数 List<Integer> arrayList = Lists.newArrayList("m","i","k","e"); // 翻转一个集合,原集合不变 List<Integer> reversed = Lists.reverse(arrayList); // 集合变换,传一个function对象,相当于stream操作 List<Integer> transformed = Lists.transform(arrayList, i -> i * 2); // 创建一个HashSet Set<Integer> hashSet = Sets.newHashSet("m","i","k","e"); // 创建一个TreeSet Set<Integer> treeSet = Sets.newTreeSet(Sets.newHashSet(4, 2, 3)); //创建HashMap和ConcurrentMap HashMap<Object, Object> hashMap = Maps.newHashMap(); ConcurrentMap<Object, Object> concurrentMap = Maps.newConcurrentMap();
3.检查参数
不是代码里面充斥着 !=null, !=””,会使你的代码看上去更好看,如下所示:
//java参数判断 if(list!=null && list.size()>0) ''' if(str!=null && str.length()>0) ''' if(str !=null && !str.isEmpty()) //使用Guava参数判断 if(!Strings.isNullOrEmpty(str)) //java参数判断 if (count <= 0) { throw new IllegalArgumentException("must be positive: " + count); } //使用Guava参数判断 Preconditions.checkArgument(count > 0, "must be positive: %s", count);
4.并发工具
ListenableFuture是jdk的Future接口的一个扩展,guava团队建议在所有使用Future的地方,使用ListenableFuture进行代替。
// 使用listeningDecorator方法包装线程池 ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10)); // 调用submit方法,即可返回ListenableFuture ListenableFuture<Explosion> explosion = service.submit( new Callable<Explosion>() { public Explosion call() { return pushBigRedButton(); } }); // 通过Futures工具类的addCallback方法,为ListenableFuture添加执行成功和失败的回调 Futures.addCallback( explosion, new FutureCallback<Explosion>() { // 执行成功 public void onSuccess(Explosion explosion) { walkAwayFrom(explosion); } // 执行失败 public void onFailure(Throwable thrown) { battleArchNemesis(); } }, service);
5.Guava缓存
Guava Cache缓存位于com.google.common.cache包下,核心的类有两个,一个是CacheBuilder,是用来构建缓存的,另一个是Cache,也就是缓存容器,用来存放缓存数据的。
Guava Cache的架构设计灵感ConcurrentHashMap,在简单场景中可以通过HashMap实现简单数据缓存,但如果要实现缓存随时间改变、存储的数据空间可控则缓存工具还是很有必要的。
@Component public class BaseCache { private Cache<String,Object> cache = CacheBuilder.newBuilder() //初始大小 .initialCapacity(10) //最大值 .maximumSize(100) //并发数 .concurrencyLevel(5) //缓存过期时间 .expireAfterWrite(600, TimeUnit.SECONDS) //缓存命中率 .recordStats() .build(); public Cache<String, Object> getCache() { return cache; } public void setCache(Cache<String, Object> cache) { this.cache = cache; } }
6.布隆过滤器
布隆过滤器可以用于检索一个元素是否在一个集合中,它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。
public class BloomTest { // 预计元素个数 private long size = 1024 * 1024; private BloomFilter<String> bloom = BloomFilter.create(new Funnel<String>() { @Override public void funnel(String from, PrimitiveSink into) { // 自定义过滤条件 此处不做任何过滤 into.putString((CharSequence) from, Charset.forName("UTF-8")); } }, size); public void fun() { // 往过滤器中添加元素 bloom.put("布隆过滤器"); // 查询 boolean mightContain = bloom.mightContain("布隆过滤器"); System.out.println(mightContain); } public static void main(String[] args) { BloomTest blBoolmTest = new BloomTest(); blBoolmTest.fun(); } }
7.IO工具
封装了一些更方便的I/O工具,如下所示:
// 将整个输入流读为byte数组,不会关闭流 byte[] bytes = ByteStreams.toByteArray(inputStream); // 将整个输入流中的字节复制到输出流中,不会关闭流或清空缓存区 long length = ByteStreams.copy(inputStream, outputStream); // 将整个输入流/可读对象中的数据按行读出,不包含换行符 List<String> lines = CharStreams.readLines(new InputStreamReader(inputStream)); // 将整个输入流/可读对象中的数据读成一个字符串,不关闭流 String s = CharStreams.toString(new InputStreamReader(inputStream));
8.反射工具
提供更方便的反射工具,如下所示:
// 获取类的包名 final String packageName = Reflection.getPackageName(Test.class); // 生成一个接口的动态代理对象 Foo foo = Reflection.newProxy(Foo.class, invocationHandler);
9.事件总线
Guava 事件总线EventBus允许在服务内部的组件之间进行发布-订阅式的通信,是观察者模式的优雅实现。
// 事件处理器 class EventBusChangeRecorder { @Subscribe public void recordCustomerChange(ChangeEvent e) { recordChange(e.getChange()); } } // 订阅事件 EventBus eventBus = new EventBus("event"); eventBus.register(new EventBusChangeRecorder()); // 创建事件 ChangeEvent e = getChangeEvent(); // 发布事件 eventBus.post(e);
陈睿mikechen
10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。
关注「mikechen」公众号,获取更多技术干货!
后台回复【面试】即可获取《史上最全阿里Java面试题总结》,后台回复【架构】,即可获取《阿里架构师进阶专题全部合集》