一、基础工具
基础类型封装 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、显式清除:任何时候,你都可以显式地清除缓存项,而不是等到它被回收:
- 个别清除:Cache.invalidate(key)
- 批量清除:Cache.invalidateAll(keys)
- 清除所有缓存项:Cache.invalidateAll()
刷新缓存
刷新和回收不太一样。正如LoadingCache.refresh(K)所声明,刷新表示为键加载新值,这个过程可以是异步的。在刷新操作进行时,缓存仍然可以向其他线程返回旧值,而不像回收操作,读缓存的线程必须等待新值加载完成。
如果刷新过程抛出异常,缓存将保留旧值,而异常会在记录到日志后被丢弃[swallowed]。