Guava —— Base & Cache

一、基础工具

基础类型封装 primitives包

1、Ints、Doubles、Chars...提供asList、contains、maxmin等方法

2、 无符号基础类:

      无符号和有符号的区别就是无符号类型能保存2倍于有符号类型的正整数数据,比如16位系统中一个short能存储的数据的范围为-32768~32767,而unsigned能存储的数据范围则是0~65535。db字段 int字段zerofill修饰补全0,前unsigned的意思就是不允许插入的数据有负数,传入负值直接插入0. int(5) unsigned zerofill 

Strings处理类

1、组合Joiner.on(",").join

2、拆分 Splitter.on(',')

3、字符匹配 CharMatcher

public class StringHandler {

    public void testJoin(){
        Joiner.on(",").join(Arrays.asList(1, 5, 7)); // returns "1,5,7"
    }

    public void testSplit(){
        Splitter.on(',');//按,将字符拆分 (char、charmatcher、string、pattern)
    }

    //字符匹配工厂
    public void testCharMatcher(){
        String string="  controljavakjflka   jsfljadsfljdlasfjladskjfkadsj23232";
        String noControl = CharMatcher.JAVA_ISO_CONTROL.removeFrom(string); //移除control字符
        String theDigits = CharMatcher.DIGIT.retainFrom(string); //只保留数字字符
        String spaced = CharMatcher.WHITESPACE.trimAndCollapseFrom(string, ' ');
        //去除两端的空格,并把中间的连续空格替换成单个空格
        String noDigits = CharMatcher.JAVA_DIGIT.replaceFrom(string, "*"); //用*号替换所有数字
        // 只保留数字和小写字母
        String lowerAndDigit = CharMatcher.JAVA_DIGIT.or(CharMatcher.JAVA_LOWER_CASE).retainFrom(string);
    
    }
}

入参 判空

Preconditions checkArgument checkNotNull

Optional of\fromNullable

区间范围 Range

      Range.closed("left", "right"); //字典序在"left"和"right"之间的字符串,闭区间
      Range.lessThan(4.0); //严格小于4.0的double值

      //区间运算
      Range.closed(1, 3).contains(2);//return true
      Range.closed(1, 3).contains(4);//return false

Objects

接口设计: 链式调用fluent接口设计风格

    //    compareTo 避免各种if () return ;if return
    public int compareTo(Foo that) {
        return ComparisonChain.start()
                .compare(this.aString, that.aString)
                .compare(this.anInt, that.anInt)
                .compare(this.anEnum, that.anEnum, Ordering.natural().nullsLast())
                .result();
    }

Ordering

数字、首字母按序排列

二、缓存

创建缓存

    public  void createCache(){
        LoadingCache<String, Graph> graphs = CacheBuilder.newBuilder()
                .maximumSize(1000)
                .build(
                        new CacheLoader<String, Graph>() {
                            //get key 异常,抛出特定exception
                            public Graph load(String key) throws AnyException {
                                return createExpensiveGraph(key);
                            }
                        });

        try {
            return graphs.get(key);
        } catch (ExecutionException e) {
            throw new OtherException(e.getCause());
        }
    }

操作缓存

public void testCacheCallable(){
        Cache<String, Graph> cache = CacheBuilder.newBuilder()
            .maximumSize(1000)
            .build(); // look Ma, no CacheLoader

        try {
            //使用cache.put(key, value)方法可以直接向缓存中插入值,这会直接覆盖掉给定键之前映射的值
            cache.get(key, new Callable<String, Graph>() {
                @Override
                public String call() throws AnyException {
                    return doThingsTheHardWay(key);
                }
            });
        } catch (ExecutionException e) {
            throw new OtherException(e.getCause());
        }
    }
注:get(K, Callable<V>)这个方法返回缓存中相应的值,或者用给定的Callable运算并把结果加入到缓存中。在整个加载方法完成前,缓存项相关的可观察状态都不会更改。这个方法简便地实现了模式"如果有缓存则返回.

释放缓存

1、基于容量回收:CacheBuilder.maximumSize(long)。缓存将尝试回收最近没有使用或总体上很少使用的缓存项。警告:在缓存项的数目达到限定值之前,缓存就可能进行回收操作,通常来说,这种情况发生在缓存项的数目逼近限定值时

     容量权重:不同的缓存项有不同的“权重”(weights)。例如,如果你的缓存值,占据完全不同的内存空间,你可以使用CacheBuilder.weigher(Weigher)指定一个权重函数,并且用CacheBuilder.maximumWeight(long)指定最大总重。在权重限定场景中,除了要注意回收也是在重量逼近限定值时就进行了,还要知道重量是在缓存创建时计算的,因此要考虑重量计算的复杂度

        LoadingCache<String, Graph> graphs = CacheBuilder.newBuilder()
                .maximumWeight(100000)
                .weigher(new Weigher<String, Graph>() {
                    public int weigh(String k, Graph g) {
                        return g.vertices().size();
                    }
                })
                .build(
                        new CacheLoader<String, Graph>() {
                            public Graph load(String key) { // no checked exception
                                return createExpensiveGraph(key);
                            }
                        });

2、基于时间回收:

(1)expireAfterAccess(long, TimeUnit):缓存项在给定时间内没有被读/写访问,则回收。请注意这种缓存的回收顺序和基于大小回收一样。

(2)expireAfterWrite(long, TimeUnit):缓存项在给定时间内没有被写访问(创建或覆盖),则回收。如果认为缓存数据总是在固定时候后变得陈旧不可用,这种回收方式是可取的。

(3)使用Ticker接口和CacheBuilder.ticker(Ticker)方法在缓存中自定义一个时间源,而不是非得用系统时钟。

3、基于引用:通过使用弱引用的键、或弱引用的值、或软引用的值,Guava Cache可以把缓存设置为允许垃圾回收:

  • CacheBuilder.weakKeys():使用弱引用存储键。当键没有其它(强或软)引用时,缓存项可以被垃圾回收。因为垃圾回收仅依赖恒等式(==),使用弱引用键的缓存用==而不是equals比较键。
  • CacheBuilder.weakValues():使用弱引用存储值。当值没有其它(强或软)引用时,缓存项可以被垃圾回收。因为垃圾回收仅依赖恒等式(==),使用弱引用值的缓存用==而不是equals比较值。
  • CacheBuilder.softValues():使用软引用存储值。软引用只有在响应内存需要时,才按照全局最近最少使用的顺序回收。考虑到使用软引用的性能影响,我们通常建议使用更有性能预测性的缓存大小限定(见上文,基于容量回收)。使用软引用值的缓存同样用==而不是equals比较值。

4、显式清除:任何时候,你都可以显式地清除缓存项,而不是等到它被回收:

刷新缓存

刷新和回收不太一样。正如LoadingCache.refresh(K)所声明,刷新表示为键加载新值,这个过程可以是异步的。在刷新操作进行时,缓存仍然可以向其他线程返回旧值,而不像回收操作,读缓存的线程必须等待新值加载完成。

如果刷新过程抛出异常,缓存将保留旧值,而异常会在记录到日志后被丢弃[swallowed]。

部分总结自:http://ifeve.com/google-guava-eventbus/

猜你喜欢

转载自blog.csdn.net/Daybreak1209/article/details/82224456