添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

Guava 是一个 Google 的基于java1.6的类库集合的扩展项目,包括 collections, caching, primitives support, concurrency libraries, common annotations, string processing, I/O, 等等. 这些高质量的 API 可以使你的JAVa代码更加优雅,更加简洁,让你工作更加轻松愉悦。

项目相关信息:

  • 官方首页:http://code.google.com/p/guava-libraries
  • 官方下载:http://code.google.com/p/guava-libraries/downloads/list
  • 官方文档:http://docs.guava-libraries.googlecode.com/git/javadoc
  • http://www.ostools.net/apidocs/apidoc?api=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:多线程工具包。
  • 类库使用手册

    一. 基本工具类:

  • 使用和避免 null:null 有语言歧义, 会产生令人费解的错误, 反正他总是让人不爽。很多 Guava 的工具类在遇到 null 时会直接拒绝或出错,而不是默默地接受他们。
  • 前提条件:更容易的对你的方法进行前提条件的测试。
  • 常见的对象方法: 简化了Object常用方法的实现, 如 hashCode() 和 toString()。
  • 排序: Guava 强大的 "fluent Comparator"比较器, 提供多关键字排序。
  • Throwable类: 简化了异常检查和错误传播。
  • 二. 集合类:集合类库是 Guava 对 JDK 集合类的扩展, 这是 Guava 项目最完善和为人所知的部分。

  • Immutable collections(不变的集合): 防御性编程, 不可修改的集合,并且提高了效率。
  • New collection types(新集合类型):JDK collections 没有的一些集合类型,主要有:multisets,multimaps,tables, bidirectional maps等等
  • Powerful collection utilities(强大的集合工具类): java.util.Collections 中未包含的常用操作工具类
  • Extension utilities(扩展工具类): 给 Collection 对象添加一个装饰器? 实现迭代器? 我们可以更容易使用这些方法。
  • 三. 缓存: 本地缓存,可以很方便的操作缓存对象,并且支持各种缓存失效行为模式。

    四. Functional idioms(函数式): 简洁, Guava实现了Java的函数式编程,可以显著简化代码。

    五. Concurrency(并发):强大,简单的抽象,让我们更容易实现简单正确的并发性代码。

  • ListenableFuture(可监听的Future): Futures,用于异步完成的回调。
  • Service: 控制事件的启动和关闭,为你管理复杂的状态逻辑。
  • 六. Strings: 一个非常非常有用的字符串工具类: 提供 splitting,joining, padding 等操作。

    七. Primitives: 扩展 JDK 中未提供的对原生类型(如int、char等)的操作, 包括某些类型的无符号的变量。

    八. Ranges: Guava 一个强大的 API,提供 Comparable 类型的范围处理, 包括连续和离散的情况。

    九. I/O: 简化 I/O 操作, 特别是对 I/O 流和文件的操作, for Java 5 and 6.

    十. Hashing: 提供比 Object.hashCode() 更复杂的 hash 方法, 提供 Bloom filters.

    十一. EventBus: 基于发布-订阅模式的组件通信,但是不需要明确地注册在委托对象中。

    十二. Math: 优化的 math 工具类,经过完整测试。

    十三. Reflection: Guava 的 Java 反射机制工具类。

    Optional

    大多数情况下开发人员使用null表示是目中缺失情况,可能是已经有一个默认值,或者没有值,或者找不到值.例如,Map.get返回null就表示找不到给定键对应的值

    Guava用Optional 表示可能为null的T类型引用。一个Optional实例可能包含非null的引用(我们称之为引用存在),也可能什么也不包括(称之为引用缺失)。它从不说包含的是null值,而是用存在或缺失来表示。但Optional从不会包含null值引用。

    Optional<Integer> possible = Optional.of(5);
    possible.isPresent();
    possible.get();
    

    创建Optional实例

    method checkElementIndex(int index, int size) 检查index作为索引值对某个列表、字符串或数组是否有效。index>=0 && index<size * IndexOutOfBoundsException checkPositionIndex(int index, int size) 检查index作为位置值对某个列表、字符串或数组是否有效。index>=0 && index<=size * IndexOutOfBoundsException checkPositionIndexes(int start, int end, int size) 检查[start, end]表示的位置范围对某个列表、字符串或数组是否有效* IndexOutOfBoundsException

    Guava – Maps

    Create Map

    Map<String, String> aNewMap = Maps.newHashMap();
    

    ImmutableMap

    @Test
    public void whenCreatingImmutableMap_thenCorrect() {
        Map<String, Integer> salary = ImmutableMap.<String, Integer> builder()
          .put("John", 1000)
          .put("Jane", 1500)
          .put("Adam", 2000)
          .put("Tom", 2000)
          .build();
        assertEquals(1000, salary.get("John").intValue());
        assertEquals(2000, salary.get("Tom").intValue());
    

    SortedMap

    @Test
    public void whenUsingSortedMap_thenKeysAreSorted() {
        ImmutableSortedMap<String, Integer> salary = new ImmutableSortedMap
          .Builder<String, Integer>(Ordering.natural())
          .put("John", 1000)
          .put("Jane", 1500)
          .put("Adam", 2000)
          .put("Tom", 2000)
          .build();
        assertEquals("Adam", salary.firstKey());
        assertEquals(2000, salary.lastEntry().getValue().intValue());
    

    BiMap

    @Test
    public void whenCreateBiMap_thenCreated() {
        BiMap<String, Integer> words = HashBiMap.create();
        words.put("First", 1);
        words.put("Second", 2);
        words.put("Third", 3);
        assertEquals(2, words.get("Second").intValue());
        assertEquals("Third", words.inverse().get(3));
    

    Multimap

    @Test
    public void whenCreateMultimap_thenCreated() {
        Multimap<String, String> multimap = ArrayListMultimap.create();
        multimap.put("fruit", "apple");
        multimap.put("fruit", "banana");
        multimap.put("pet", "cat");
        multimap.put("pet", "dog");
        assertThat(multimap.get("fruit"), containsInAnyOrder("apple", "banana"));
        assertThat(multimap.get("pet"), containsInAnyOrder("cat", "dog"));
    

    Table

    @Test
    public void whenCreatingTable_thenCorrect() {
        Table<String,String,Integer> distance = HashBasedTable.create();
        distance.put("London", "Paris", 340);
        distance.put("New York", "Los Angeles", 3940);
        distance.put("London", "New York", 5576);
        assertEquals(3940, distance.get("New York", "Los Angeles").intValue());
        assertThat(distance.columnKeySet(), 
          containsInAnyOrder("Paris", "New York", "Los Angeles"));
        assertThat(distance.rowKeySet(), containsInAnyOrder("London", "New York"));
    @Test
    public void whenTransposingTable_thenCorrect() {
        Table<String,String,Integer> distance = HashBasedTable.create();
        distance.put("London", "Paris", 340);
        distance.put("New York", "Los Angeles", 3940);
        distance.put("London", "New York", 5576);
        Table<String, String, Integer> transposed = Tables.transpose(distance);
        assertThat(transposed.rowKeySet(), 
          containsInAnyOrder("Paris", "New York", "Los Angeles"));
        assertThat(transposed.columnKeySet(), containsInAnyOrder("London", "New York"));
    

    ClassToInstanceMap

    @Test
    public void whenCreatingClassToInstanceMap_thenCorrect() {
        ClassToInstanceMap<Number> numbers = MutableClassToInstanceMap.create();
        numbers.putInstance(Integer.class, 1);
        numbers.putInstance(Double.class, 1.5);
        assertEquals(1, numbers.get(Integer.class));
        assertEquals(1.5, numbers.get(Double.class));
    

    Group List using Multimap

    @Test
    public void whenGroupingListsUsingMultimap_thenGrouped() {
        List<String> names = Lists.newArrayList("John", "Adam", "Tom");
        Function<String,Integer> func = new Function<String,Integer>(){
            public Integer apply(String input) {
                return input.length();
        Multimap<Integer, String> groups = Multimaps.index(names, func);
        assertThat(groups.get(3), containsInAnyOrder("Tom"));
        assertThat(groups.get(4), containsInAnyOrder("John", "Adam"));
    

    Guava StopWatch

    import com.google.common.base.Stopwatch;
    import java.util.concurrent.TimeUnit;
    public class GuavaStopWatch {
        public static void main(String[] args) {
            printTitle("StopWatch Start ");
            int countingDown=10;
            Stopwatch stopwatch=Stopwatch.createUnstarted();
            stopwatch.elapsed(TimeUnit.SECONDS);
            stopwatch.start();
            while(countingDown>0){
                try {
                    Thread.sleep(1000);
                }catch (Exception e){
                    println(e.getMessage());
                println("StopWatch Is Running ? --> "+stopwatch.isRunning());
                println("StopWatch Time is "+stopwatch);
                countingDown--;
            printTitle("End Of Looping");
            println("Check Total Time is Needed: "+stopwatch);
            stopwatch.stop();
    

    GuavaCache

    Guava Cache是在内存中缓存数据,相比较于数据库或redis存储,访问内存中的数据会更加高效。

    Guava官网介绍,下面的这几种情况可以考虑使用Guava Cache:

  • 愿意消耗一些内存空间来提升速度。
  • 预料到某些键会被多次查询。
  • 缓存中存放的数据总量不会超出内存容量。
  • <dependency>  
        <groupId>com.google.guava</groupId>  
        <artifactId>guava</artifactId>  
        <version>19.0</version>  
    </dependency>  
    

    构建缓存对象

    接口Cache代表一块缓存,它有如下方法:

    public interface Cache<K, V> {
        V get(K key, Callable<? extends V> valueLoader) throws ExecutionException;
        ImmutableMap<K, V> getAllPresent(Iterable<?> keys);
        void put(K key, V value);
        void putAll(Map<? extends K, ? extends V> m);
        void invalidate(Object key);
        void invalidateAll(Iterable<?> keys);
        void invalidateAll();
        long size();
        CacheStats stats();
        ConcurrentMap<K, V> asMap();
        void cleanUp();
    

    可以通过CacheBuilder类来构建一个缓存对象,CacheBuilder类采用builder设计模式,它的每个方法都返回CacheBuilder本身,直到builder()方法被调用,构建一个缓存对象的代码如下:

    public class StudyGuavaCache {
        public static void main(String[] args) {
            Cache<String,String> cache = CacheBuilder.newBuilder().build();
            cache.put("word","Hello Guava Cache");
            System.out.println(cache.getIfPresent("word"));
    

    上面的代码通过CacheBuilder.newBuilder().build()这句代码创建了一个Cache缓存对象,并在缓存对象中存储了key为word,value为Hello Guava Cache的一条记录。可以看到Cache非常类似于JDK中的Map,但是相比于Map,Guava Cache提供了很多更强大的功能。

    设置最大存储

    Guava Cache可以设置在构建缓存对象的时候指定缓存所存储的最大记录数量.当Cache中的记录数量达到最大值后再调用put方法向其中添加对象Guava会先从当前缓存的对象记录中选择一条删除掉,腾出空间后再将新的对象存储到Cache中。

    public class StudyGuavaCache {
        public static void main(String[] args) {
            Cache<String,String> cache = CacheBuilder.newBuilder()
                    .maximumSize(2)
                    .build();
            cache.put("key1","value1");
            cache.put("key2","value2");
            cache.put("key3","value3");
            System.out.println("第一个值:" + cache.getIfPresent("key1"));
            System.out.println("第二个值:" + cache.getIfPresent("key2"));
            System.out.println("第三个值:" + cache.getIfPresent("key3"));
    

    上面代码在构造缓存对象时,通过CacheBuilder类的maximumSize方法指定Cache最多可以存储两个对象,然后调用Cache的put方法向其中添加了三个对象。程序执行结果如下图所示,可以看到第三条对象记录的插入,导致了第一条对象记录被删除。

    移除监听器

    可以为Cache对象添加一个移除监听器,这样当有记录被删除时可以感知到这个事件。

    public class StudyGuavaCache {
        public static void main(String[] args) throws InterruptedException {
            RemovalListener<String, String> listener = new RemovalListener<String, String>() {
                public void onRemoval(RemovalNotification<String, String> notification) {
                    System.out.println("[" + notification.getKey() + ":" + notification.getValue() + "] is removed!");
            Cache<String,String> cache = CacheBuilder.newBuilder()
                    .maximumSize(3)
                    .removalListener(listener)
                    .build();
            Object value = new Object();
            cache.put("key1","value1");
            cache.put("key2","value2");
            cache.put("key3","value3");
            cache.put("key4","value3");
            cache.put("key5","value3");
            cache.put("key6","value3");
            cache.put("key7","value3");
            cache.put("key8","value3");
    

    removalListener方法为Cache指定了一个移除监听器,这样当有记录从Cache中被删除时,监听器listener就会感知到这个事件。程序运行结果如下图所示

    http://ifeve.com/google-guava-collectionutilities/

    Guava Cache用法介绍