`
hadix
  • 浏览: 25222 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Guava学习笔记

    博客分类:
  • java
阅读更多
Guava是Google的Java核心库,基于Java5+.

Guava由

com.google.common.annotations 
com.google.common.base 
com.google.common.base.internal 
com.google.common.collect 
com.google.common.io 
com.google.common.net 
com.google.common.primitives 
com.google.common.util.concurrent 


这些包组成.其中base包中提供了一些与commons-lang类似的功能类.比如toString,equals方法的构造器.字符串处理的相关静态方法.但是Guava中提供等价功能的API更加易用,也更灵活.现在就从base包开始讲起.

[size=small;]com.google.common.base[/size]
Objects类
public class Person {
	final String name, nickname;
	final Movie favMovie;
	@Override public boolean equals(Object object) {
		if (object instanceof Person) {
		Person that = (Person) object;
		return Objects.equal(this.name, that.name)
				&& Objects.equal(this.nickname, that.nickname)
				&& Objects.equal(this.favMovie, that.favMovie);
		}
		return false;
	}
	@Override public int hashCode() {
		return Objects.hashCode(name, nickname, favMovie);
	}
	@Override public String toString() {
		return Objects.toStringHelper(this)
			.add("name", name)
			.add("nickname", nickname)
			.add("favMovie", favMovie)
			.toString();
	}
	public String preferredName() {
		return Objects.firstNonNull(nickname, name);
	}

上述代码显示了Objects中几乎所有方法.此外还有一个equal静态方法.方法签名如下:
static boolean equal(Object a, Object b)
该方法可以安全的传入null值,避免抛出NullPointerException.
Preconditions类
这个类提供了一些静态方法check*,可以使用这些方法在自己的方法中检查参数的正确性.
if (state != State.PLAYABLE) {
      throw new IllegalStateException("Can't play movie; state is " + state);
}

上述代码可以替换为如下
Preconditions.checkState(state == State.PLAYABLE,"Can't play movie; state is %s", state);


字符串处理相关的类CharMathcer,Joiner,Splitter.
这些类都使用了链式调用做配置,所以使用起来非常方便灵活,行为的可定制性极强.
所谓的字符串处理无非是找到指定的字符提取出来,然后进一步做处理.
CharMatcher就是做查找提取字符串的类,在一定程度上可以代替正则表达式做字符串匹配,但是其API要比使用正则表达式更容易些.写出的代码的可读性当然是正则表达式不可比拟的.
该类的声明中有@Beta标注,API尚不稳定,不建议在工作项目中使用.还是乖乖是用正则表达式吧.
//使用预定义常量构建CharMatcher实例
CharMatcher.WHITESPACE (tracks Unicode defn.)
CharMatcher.JAVA_DIGIT
CharMatcher.ASCII
CharMatcher.ANY
//使用工厂方法构建CharMatcher实例
CharMatcher.is('x')
CharMatcher.isNot('_')
CharMatcher.oneOf("aeiou").negate()
CharMatcher.inRange('a', 'z').or(inRange('A', 'Z'))
//或者继承CharMatcher并实现自己的matches(char c)方法.

得到一个CharMatcher实例后,可以对该实例进行如下操作
boolean matchesAllOf(CharSequence)
boolean matchesAnyOf(CharSequence)
boolean matchesNoneOf(CharSequence)
int indexIn(CharSequence, int)
int lastIndexIn(CharSequence, int)
int countIn(CharSequence)
String removeFrom(CharSequence)
String retainFrom(CharSequence)
String trimFrom(CharSequence)
String trimLeadingFrom(CharSequence)
String trimTrailingFrom(CharSequence)
String collapseFrom(CharSequence, char)
String trimAndCollapseFrom(CharSequence, char)
String replaceFrom(CharSequence, char)

使用示例:
String seriesId =
CharMatcher.DIGIT.or(CharMatcher.is('-'))
.retainFrom(input);


Joiner用来组合字符串
//使用一个分隔符来连接文本片段
String s = Joiner.on(", ").join(episodesOnDisc);
//Joiner实例是可配置的
StringBuilder sb = ...;
Joiner.on("|").skipNulls().appendTo(sb, attrs);
//甚至可以使用Joiner处理Map类型
static final MapJoiner MAP_JOINER = Joiner.on("; ")
.useForNull("NODATA")
.withKeyValueSeparator(":");


注意该类是不可变的所以如下的代码是错误的
  
// 直接在实例上调用配置方法对该实例并无影响,需要使用配置方法的返回值.
   Joiner joiner = Joiner.on(',');
   joiner.skipNulls(); // does nothing!
   return joiner.join("wrong", null, "wrong");


Splitter类,如其名可知与Joiner相反该类用来将文本分隔成片段,对比JDK中的split方法,Splitter更加灵活,行为也更加明确.
使用Spltter做文本分隔,可以选择如下形式的分隔符
  • 一个单独的字符: Splitter.on('\n')
  • 一个字符串字面量: Splitter.on(", ")
  • 一个正则表达式: Splitter.onPattern(",\\s*")
  • 任何的CharMatcher实例(上面提到过的)
  • 使用固定的长度: Splitter.fixedLength(8)

使用示例
Iterable<String> pieces =
Splitter.on(',').split("trivial,example")
//按顺序返回"trivial"和"example"


String.split方法需要使用正则表达式,返回数组.
Splitter更加灵活
//默认的行为十分简单明了
//[" foo", " ", "bar", " quux", ""]
Splitter.on(',').split(" foo, ,bar, quux,")
If you want extra features, ask for them!
//["foo", "bar", "quux"]
Splitter.on(',').trimResults().omitEmptyStrings().split(" foo, ,bar, quux,")
//配置方法的顺序无关紧要


Strings类提供了几个字符串相关的静态工具方法
emptyToNull,nullToEmpty,padStart,padEnd,repeat,isNullOrEmpty.只要看到这些方法名称就知道方法的行为和用法了.再此就不多讲了.

除了上述的常用功能类外,base包中还提供了一些基本的抽象接口.
例如Function,Predicate,Supplier,以及相关的Functions,Predicates,Suppliers工具类.有关这部分内容在之后的连载中结合其它的包进行说明.

[size=small;]com.google.common.primitives[/size]
这是一个帮助开发者使用原始类型的包,如果开发者需要使用原始类型相关的方法,现在可以
  • 检查原始类型的包装器类
  • 检查java.util.Arrays
  • 检查com.google.common.primitives
  • 如果都没有那可能不存在需要的方法

方法如下表所示
MethodLongsIntsShortsCharsDoublesBytesS.BytesU.BytesBooleans
hashCodeXXXXXXX
compareXXXXXXXX
checkedCastXXXXX
saturatedCastXXXXX
containsXXXXXX
indexOfXXXXXXX
lastIndexOfXXXXXXX
minXXXXXXX
maxXXXXXXX
concatXXXXXXX
joinXXXXXXXX
toArrayXXXXXXX
asListXXXXXXX
lexComparatorXXXXXXXX
toByteArrayXXXX
fromByteArrayXXXX


[size=small;]com.google.common.io/size]
如果要使用流,文件,缓存之类输入输出的操作,就可以看看这个包提供的内容.

这里就要说一下base包中的Supplier接口,该接口可以提供一种类型的对象,从语义上讲类似于工厂,生成器,构造器等等,具体行为当然是依赖于实现的.
Suppliers中提供了一些获取有用的Supplier实例的静态方法.例如ofInstance(T instance) ,调用该方法可以得到一个永远返回instance的supplier.
memoize(Supplier<T> delegate) 会缓存第一次调用get()得到的值(这个值使用delegate的get方法得到),在接下来对get()的调用时返回该值.
synchronizedSupplier(Supplier<T> delegate) 显而易见,调用该方法可以得到delegate的线程安全版本,对delegate的get操作施加同步处理.

下面是io包中的两个关键接口
public interface InputSupplier<T> {
      T getInput() throws IOException;
}
public interface OutputSupplier<T> {
      T getOutput() throws IOException;
}


例如:InputSupplier<InputStream>,OutputSupplier<Writer>等等,这样可以使包中的实用工具对各种类型的I/O都有用.

ByteStrsams和CharStreams分别是对应字节流(InputStream,OutputStream)和字符流(Reader,Writer)的使用工具类.
ByteStreams提供的操作如下:
  • byte[] toByteArray(InputStream)
  • byte[] toByteArray(InputSupplier)
  • void readFully(InputStream, byte[])
  • void write(byte[], OutputSupplier)
  • long copy(InputStream, OutputStream)
  • long copy(InputSupplier, OutputSupplier)
  • long length(InputSupplier)
  • boolean equal(InputSupplier, InputSupplier)
  • InputSupplier slice(InputSupplier, long, long)
  • InputSupplier join(InputSupplier...)

CharStreams提供的操作也是类似的,只是将处理的目标换成Reader,Writer,String和CharSequence(而且这些操作通常需要指定一个Charset)

Files顾名思义是跟File一起工作的实用工具类,提供比ByteStreams,CharStreams更好抽象等级的操作.如下
  • byte[] toByteArray(File)
  • String toString(File, Charset)
  • void write(byte[], File)
  • void write(CharSequence, File, Charset)
  • long copy(File, File)
  • long copy(InputSupplier, File)
  • long copy(File, OutputSupplier)
  • long copy(File, Charset, Appendable)
  • long move(File, File)
  • boolean equal(File, File)
  • List<String> readLines(File, Charset)

JDK7 有更合适的io操作抽象API和语法.待JDK7正式发布的时候,或许就不再需要其他的第三方io实用工具包了.
1
2
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics