[toc]
guava: google 的开源工具包
帮助编写常用方法
hashCode,equals,toString,compareTo方法;前三个idea 提供了guava方式的代码生成
import com.google.common.base.MoreObjects;
import com.google.common.collect.ComparisonChain;
public class User implements Comparable{
private String name;
private int age;
//omit setting and getting
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return age == user.age &&
com.google.common.base.Objects.equal(name, user.name);
}
@Override
public int hashCode() {
return com.google.common.base.Objects.hashCode(name, age);
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("name", name)
.add("age", age)
.toString();
}
@Override
public int compareTo(User other) {
return ComparisonChain.start().
compare(this.name,other.name).
compare(this.age,other.age).
result();
}
}
检查方法调用的前置条件
一般尽快失败来拒绝不符合条件的调用
private void addAge(User user,int age){
//检查非空, throw NullPointerException
Preconditions.checkNotNull(user,"%s must not be null","user");
//检查参数,throw IllegalArgumentException
Preconditions.checkArgument(age>0,"the %s should greater than 0; now: %s","age",age);
//检查对象的状态,throw IllegalStateException
Preconditions.checkState(user.getAge()>10,"the age of %s should larger than 10; now: %s",user.getName(),2);
//检查index作为索引值对某个列表、字符串或数组是否有效。 throw IndexOutOfBoundsException
List list = new ArrayList<>();
int size = list.size();
for (int i = 0; i < size; i++) {
Preconditions.checkElementIndex(i,size);
Preconditions.checkPositionIndex(i,size);
}
}
集合
支持空元素集合 | 不支持空元素集合 |
---|---|
JDK 中的集合很多都支持空元素(ArrayList,LinkedList, HashSet, HashMap) | EnumMap,ConcurrentHashMap 和 guava中的集合大多不支持空元素 |
Enum,Tree类型支持不支持看compare方法,TreeSet不支持空元素。TreeMap支持空元素。
最好严格控制不存null,防止出问题
转换成不可变集合
guava方式 比 Collections.unmodifiableXXX方法 更高效和安全;
最好使用 static final 显示声明,更明显
//使用of 方法直接构建不可变集合
public static final ImmutableSet COLOR_NAMES = ImmutableSet.of(
"red","orange","yellow","green","blue","purple");
//使用copyOf 转换成不可变集合
ImmutableList immutableList = ImmutableList.copyOf(Collection);
ImmutableSet immutableSet = ImmutableSet.copyOf(Collection);
ImmutableMap immutableMap = ImmutableMap.copyOf(Map);
jdk可变集合接口 | guava中不可变版本 |
---|---|
Collection | ImmutableCollection |
List | ImmutableList |
Set | ImmutableSet |
SortedSet/NavigableSet | ImmutableSortedSet |
Map | ImmutableMap |
SortedMap | ImmutableSortedMap |
新集合类型
Multiset
可以多次添加相等的元素 统计出现的次数;
Multiset set = HashMultiset.create();
//Multiset set = TreeMultiset.create();
//Multiset set = LinkedHashMultiset.create();
//Multiset set = ConcurrentHashMultiset.create();
//Multiset set = ImmutableMultiset.copyOf(set);
set.add("a");
set.add("b");
set.setCount("c",101);
System.out.println(set.count("c")); //101
System.out.println(set.size()); //103
Multimap
允许key重复
//注意Multimap不是Map>,里面的key是有重复的,但entry(key & value)不能都一样
Multimap multimap = HashMultimap.create();
//Multimap multimap = TreeMultimap.create();
//Multimap multimap = LinkedListMultimap.create();
//ImmutableMultimap.copyOf(multimap);
multimap.put("1","2");
multimap.put("4","22");
multimap.put("13",null);
multimap.put("13","23");
multimap.put("13","23");
multimap.put("2","2");
System.out.println(multimap.get("13").size()); //2
BiMap
key和value都唯一,双向绑定,可以反转 key-value
BiMap bitMap = HashBiMap.create();
//TreeMultimap.create();
//BiMap bitMap2 = EnumBiMap.create(DemoEnum.class,OtherEnum.class);
bitMap.put("a",97);
bitMap.put("b",98);
bitMap.put("c",99);
BiMap inverseMap = bitMap.inverse();
System.out.println(bitMap.get("a")); //97
System.out.println(inverseMap.get(97)); //'a'
table
用"列"和"行" 组合做key
//泛型参数分别是:列,行,值
HashBasedTable table = HashBasedTable.create();
//TreeBasedTable.create();
//ImmutableTable.copyOf(table);
table.put(1,1,"1");
table.put(1,2,"2");
table.put(1,3,"3");
table.put(2,1,"4");
table.put(2,2,"5");
table.put(2,3,"6");
Map map1 = table.row(2); //检索第二列 {1=4, 2=5, 3=6}
Map map2 = table.column(1); //检索第一行 {1=1, 2=4}
String value = table.get(1,3); //3
ClassToInstanceMap
它的键是类型,而值是符合键所指类型的对象
//泛型参数代表Map支持的类型的上界
MutableClassToInstanceMap map = MutableClassToInstanceMap.create();
//ImmutableClassToInstanceMap.copyOf(map);
map.put(Integer.class,1);
map.put(Long.class,101L);
map.put(BigDecimal.class,BigDecimal.ONE);
map.put(short.class,Short.MAX_VALUE);
System.out.println(map.getInstance(short.class)); //32767
RangeSet,TreeRangeMap
不相连的、非空的区间
//使用Comparable 比较
//RangeSet会合并区间,RangeMap不会合并区间
RangeSet rangeSet = TreeRangeSet.create();
rangeSet.add(Range.closedOpen(0,10));
rangeSet.add(Range.closed(10,20));
rangeSet.add(Range.openClosed(21,30));
System.out.println(rangeSet.toString()); //[[0..20], (21..30]
TreeRangeMap treeRangeMap = TreeRangeMap.create();
treeRangeMap.put(Range.closed("a","f"),"a");
treeRangeMap.put(Range.closed("h","z"),"b");
treeRangeMap.remove(Range.closed("c","d"));
System.out.println(treeRangeMap.toString()); //[[a..c)=a, (d..f]=a, [h..o]=b]
字符串处理
Joiner Splitter
连接
Joiner joiner = Joiner.on(":").skipNulls(); //skipNulls()方法是直接忽略null,否者null报错
//Joiner.on(":").useForNull("defalut value"); useForNull(String)方法可以给定某个字符串来替换null
String str = joiner.join("A", null, "B", "C");
System.out.print(str); //A:B:C
分割
//jdk
String[] arr = ",a,,b ,".split(","); //结果:"", "a","", "b " 只有尾部的空字符串被忽略了。
//guava
//支持字符串,正则,长度,CharMatcher分割方式
//限制十个, 忽略空元素, 对分割后的每个元素进行trim
Iterable iterable = Splitter.on(",").limit(10).omitEmptyStrings().trimResults().split(",a,,b ,"); //结果:"a","b"
Splitter.fixedLength(3).split("aaabbbcccdd"); //按固定长度拆分;最后一段可能比给定长度短,但不会为空。
Splitter.onPattern("\\d").split("abc123de"); //正则分割
Joiner Splitter 类似BigDecimal都是不可变的
Joiner joiner = Joiner.on(',');
joiner.skipNulls(); // does nothing!
参考
https://github.com/google/guava
http://ifeve.com/google-guava/