Guava详解(定义作用及9大使用方法)

Guava详解(定义作用及9大使用方法)-mikechen

Guava定义

Guava是Google的一个开源Java框架,包含许多 Google 内部 Java 项目依赖的核心类,包括:从集合类型、不可变集合、图结构处理、并发工具、I/O、哈希、缓存等等各个方面的工具。

Guava详解(定义作用及9大使用方法)-mikechen

 

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:多线程工具包。
  1. 集合;
  2. 缓存;
  3. 原生类型支持 ;
  4. 并发库;
  5. 通用注解;
  6. 字符串处理;
  7. 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面试题总结》,后台回复架构,即可获取《阿里架构师进阶专题全部合集

评论交流
    说说你的看法