[Java工具集]Google Guava 常用功能
来源:互联网 发布:java shiro demo 编辑:程序博客网 时间:2024/05/29 09:15
Google Guava简介
引言
Guava工程包含了若干被Google的 Java项目广泛依赖 的核心库,例如:集合 [collections] 、缓存 [caching] 、原生类型支持 [primitives support] 、并发库 [concurrency libraries] 、通用注解 [common annotations] 、字符串处理 [string processing] 、I/O 等等。 所有这些工具每天都在被Google的工程师应用在产品服务中。
查阅Javadoc并不一定是学习这些库最有效的方式。在此,我们希望通过此文档为Guava中最流行和最强大的功能,提供更具可读性和解释性的说明。
译文格式说明
- Guava中的类被首次引用时,都会链接到Guava的API文档。如:Optional<T>。
- Guava和JDK中的方法被引用时,一般都会链接到Guava或JDK的API文档,一些人所共知的JDK方法除外。如:Optional.of(T), Map.get(key)。
- 译者对文档的额外说明以斜体显示,并且以“译者注:”开始。
目录
1. 基本工具 [Basic utilities]
让使用Java语言变得更舒适
1.1 使用和避免null:null是模棱两可的,会引起令人困惑的错误,有些时候它让人很不舒服。很多Guava工具类用快速失败拒绝null值,而不是盲目地接受
1.2 前置条件: 让方法中的条件检查更简单
1.3 常见Object方法: 简化Object方法实现,如hashCode()和toString()
1.4 排序: Guava强大的”流畅风格比较器”
1.5 Throwables:简化了异常和错误的传播与检查
2. 集合[Collections]
Guava对JDK集合的扩展,这是Guava最成熟和为人所知的部分
2.1 不可变集合: 用不变的集合进行防御性编程和性能提升。
2.2 新集合类型: multisets, multimaps, tables, bidirectional maps等
2.3 强大的集合工具类: 提供java.util.Collections中没有的集合工具
2.4 扩展工具类:让实现和扩展集合类变得更容易,比如创建Collection的装饰器,或实现迭代器
3. 缓存[Caches]
Guava Cache:本地缓存实现,支持多种缓存过期策略
4. 函数式风格[Functional idioms]
Guava的函数式支持可以显著简化代码,但请谨慎使用它
5. 并发[Concurrency]
强大而简单的抽象,让编写正确的并发代码更简单
5.1 ListenableFuture:完成后触发回调的Future
5.2 Service框架:抽象可开启和关闭的服务,帮助你维护服务的状态逻辑
6. 字符串处理[Strings]
非常有用的字符串工具,包括分割、连接、填充等操作
7. 原生类型[Primitives]
扩展 JDK 未提供的原生类型(如int、char)操作, 包括某些类型的无符号形式
8. 区间[Ranges]
可比较类型的区间API,包括连续和离散类型
9. I/O
简化I/O尤其是I/O流和文件的操作,针对Java5和6版本
10. 散列[Hash]
提供比Object.hashCode()更复杂的散列实现,并提供布鲁姆过滤器的实现
11. 事件总线[EventBus]
发布-订阅模式的组件通信,但组件不需要显式地注册到其他组件中
12. 数学运算[Math]
优化的、充分测试的数学工具类
13. 反射[Reflection]
Guava 的 Java 反射机制工具类
原创文章,转载请注明: 转载自并发编程网 – ifeve.com
1、 Preconditions,前置条件判断
- 没有额外参数:抛出的异常中没有错误消息;
- 有一个Object对象作为额外参数:抛出的异常使用Object.toString() 作为错误消息;
- 有一个String对象作为额外参数,并且有一组任意数量的附加Object对象:这个变种处理异常消息的方式有点类似printf,但考虑GWT的兼容性和效率,只支持%s指示符。例如:
1
checkArgument(i >=
0
,
"Argument was %s but expected nonnegative"
, i);
2
checkArgument(i < j,
"Expected i < j, but %s > %s"
, i, j);
方法声明(不包括额外参数)描述检查失败时抛出的异常checkArgument(boolean)检查boolean是否为true,用来检查传递给方法的参数。IllegalArgumentExceptioncheckNotNull(T)检查value是否为null,该方法直接返回value,因此可以内嵌使用checkNotNull。NullPointerExceptioncheckState(boolean)用来检查对象的某些状态。IllegalStateExceptioncheckElementIndex(int index, int size)检查index作为索引值对某个列表、字符串或数组是否有效。index>=0 && index<size *IndexOutOfBoundsExceptioncheckPositionIndex(int index, int size)检查index作为位置值对某个列表、字符串或数组是否有效。index>=0 && index<=size *IndexOutOfBoundsExceptioncheckPositionIndexes(int start, int end, int size)检查[start, end]表示的位置范围对某个列表、字符串或数组是否有效*IndexOutOfBoundsException2、常见Object方法
equals:bjects.equal(
"a"
,
"a"
);
// returns true
hashCode:Object.hashCode(Object ..)
compare:使用 ComparisonChain类:
实现一个比较器[Comparator],或者直接实现Comparable接口有时也伤不起。考虑一下这种情况:
01
class
Person
implements
Comparable<Person> {
02
private
String lastName;
03
private
String firstName;
04
private
int
zipCode;
05
06
public
int
compareTo(Person other) {
07
int
cmp = lastName.compareTo(other.lastName);
08
if
(cmp !=
0
) {
09
return
cmp;
10
}
11
cmp = firstName.compareTo(other.firstName);
12
if
(cmp !=
0
) {
13
return
cmp;
14
}
15
return
Integer.compare(zipCode, other.zipCode);
16
}
17
}
这部分代码太琐碎了,因此很容易搞乱,也很难调试。我们应该能把这种代码变得更优雅,为此,Guava提供了ComparisonChain。
ComparisonChain执行一种懒比较:它执行比较操作直至发现非零的结果,在那之后的比较输入将被忽略。
1
public
int
compareTo(Foo that) {
2
return
ComparisonChain.start()
3
.compare(
this
.aString, that.aString)
4
.compare(
this
.anInt, that.anInt)
5
.compare(
this
.anEnum, that.anEnum, Ordering.natural().nullsLast())
6
.result();
7
}
链式调用方法:通过链式调用,可以由给定的排序器衍生出其它排序器
方法描述reverse()获取语义相反的排序器nullsFirst()使用当前排序器,但额外把null值排到最前面。nullsLast()使用当前排序器,但额外把null值排到最后面。compound(Comparator)合成另一个比较器,以处理当前排序器中的相等情况。lexicographical()基于处理类型T的排序器,返回该类型的可迭代对象Iterable<T>的排序器。onResultOf(Function)对集合中元素调用Function,再按返回值用当前排序器排序。例如,你需要下面这个类的排序器。
class Foo { @Nullable String sortedBy; int notSortedBy;}
考虑到排序器应该能处理sortedBy为null的情况,我们可以使用下面的链式调用来合成排序器:
Ordering<Foo> ordering = Ordering.natural().nullsFirst().onResultOf(new Function<Foo, String>() { public String apply(Foo foo) { return foo.sortedBy; }});
当阅读链式调用产生的排序器时,应该从后往前读。上面的例子中,排序器首先调用apply方法获取sortedBy值,并把sortedBy为null的元素都放到最前面,然后把剩下的元素按sortedBy进行自然排序。之所以要从后往前读,是因为每次链式调用都是用后面的方法包装了前面的排序器。
注:用compound方法包装排序器时,就不应遵循从后往前读的原则。为了避免理解上的混乱,请不要把compound写在一长串链式调用的中间,你可以另起一行,在链中最先或最后调用compound。
超过一定长度的链式调用,也可能会带来阅读和理解上的难度。我们建议按下面的代码这样,在一个链中最多使用三个方法。此外,你也可以把Function分离成中间对象,让链式调用更简洁紧凑。
Ordering<Foo> ordering = Ordering.natural().nullsFirst().onResultOf(sortKeyFunction)4、字符串处理
大小写:CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL,
"CONSTANT_NAME"
));
// returns "constantName"
字符集:不需要做异常处理:bytes = string.getBytes(Charsets.UTF_8);
collapseFrom(CharSequence, char):把每组连续的匹配字符替换为特定字符。如WHITESPACE.collapseFrom(string, ‘ ‘)把字符串中的连续空白字符替换为单个空格。
matchesAllOf(CharSequence): 测试是否字符序列中的所有字符都匹配。
removeFrom(CharSequence): 从字符序列中移除所有匹配字符。
retainFrom(CharSequence): 在字符序列中保留匹配字符,移除其他字符。
trimFrom(CharSequence): 移除字符序列的前导匹配字符和尾部匹配字符。
replaceFrom(CharSequence, CharSequence):用特定字符序列替代匹配字符
5、
可以简化集合的创建和初始化;
类别原来的写法guava的写法集合创建Map<String, Map<String, String>> map = new HashMap<String, Map<String,String>>();
List<List<Map<String, String>>> list = new ArrayList<List<Map<String,String>>>();
Map<String, Map<String, String>> map = Maps.newHashMap();
List<List<Map<String, String>>> list = Lists.newArrayList();
//1,简化集合的创建
List<Person> personList= Lists.newLinkedList();
Set<Person> personSet= Sets.newHashSet();
Map<String,Person> personMap= Maps.newHashMap();
Integer[] intArrays= ObjectArrays.newArray(Integer.class,10);
Set<String> set = new HashSet<String>();
set.add("one");
set.add("two");
set.add("three");
Set<String> set = Sets.newHashSet("one","two","three");
List<String> list = Lists.newArrayList("one","two","three");
Map<String, String> map = ImmutableMap.of("ON","TRUE","OFF","FALSE");
//2,简化集合的初始化
List<Person> personList2= Lists.newArrayList(new Person(1, 1, "a", "46546", 1, 20),
new Person(2, 1, "a", "46546", 1, 20));
Set<Person> personSet2= Sets.newHashSet(new Person(1,1,"a","46546",1,20),
new Person(2,1,"a","46546",1,20));
Map<String,Person> personMap2= ImmutableMap.of("hello",new Person(1,1,"a","46546",1,20),"fuck",new Person(2,1,"a","46546",1,20));
3.2 不变性
很大一部分是google集合提供了不变性,不变对比可变:
- 数据不可改变
- 线程安全
- 不需要同步逻辑
- 可以被自由的共享
- 容易设计和实现
- 内存和时间高效
不变对比不可修改
google的不变被确保真正不可改变,而不可修改实际上还是可以修改数据;如下所示:
Set<Integer> data = new HashSet<Integer>();
data.addAll(Arrays.asList(10, 20, 30, 40, 50, 60, 70, 80));
Set<Integer> fixedData = Collections.unmodifiableSet(data); // fixedData - [50, 70, 80, 20, 40, 10, 60, 30]
data.add(90); // fixedData - [50, 70, 80, 20, 40, 10, 90, 60, 30]
如何创建不可变的集合:
ImmutableSet<Integer> numbers = ImmutableSet.of(10, 20, 30, 40, 50);
使用copyOf方法
ImmutableSet<Integer> another = mmutableSet.copyOf(numbers);
使用Builder方法
ImmutableSet<Integer> numbers2 = ImmutableSet.<Integer>builder().addAll(numbers) .add(60) .add(70).add(80).build();
//3,创建不可变的集合
ImmutableList<Person> personImmutableList=
ImmutableList.of(new Person(1, 1, "a", "46546", 1, 20), new Person(2, 1, "a", "46546", 1, 20));
ImmutableSet<Person> personImmutableSet=ImmutableSet.copyOf(personSet2);
ImmutableMap<String,Person> personImmutableMap=ImmutableMap.<String,Person>builder()
.put("hell",new Person(1,1,"a","46546",1,20)).putAll(personMap2) .build();
3.3 新的集合类型
The Guava API provides very useful new collection types that work very nicely with existing java collections.
guava API 提供了有用的新的集合类型,协同已经存在的java集合工作的很好。
分别是 MultiMap, MultiSet, Table, BiMap, ClassToInstanceMap
种类写的例子MultiMap一种key可以重复的map,子类有ListMultimap和SetMultimap,对应的通过key分别得到list和set
Multimap<String, Person> customersByType =ArrayListMultimap.create();customersByType.put("abc", new Person(1, 1, "a", "46546", 1, 20));
customersByType.put("abc", new Person(1, 1, "a", "46546", 1, 30));
customersByType.put("abc", new Person(1, 1, "a", "46546", 1, 40));
customersByType.put("abc", new Person(1, 1, "a", "46546", 1, 50));
customersByType.put("abcd", new Person(1, 1, "a", "46546", 1, 50));
customersByType.put("abcde", new Person(1, 1, "a", "46546", 1, 50));
for(Person person:customersByType.get("abc"))
{
System.out.println(person.getAge());
}
不是集合,可以增加重复的元素,并且可以统计出重复元素的个数,例子如下:
private static void testMulitiSet() {
Multiset<Integer> multiSet = HashMultiset.create();
multiSet.add(10);
multiSet.add(30);
multiSet.add(30);
multiSet.add(40);
System.out.println( multiSet.count(30)); // 2
System.out.println( multiSet.size()); //4
}
相当于有两个key的map,不多解释
private static void testTable() {
Table<Integer,Integer,Person> personTable=HashBasedTable.create();
personTable.put(1,20,new Person(1, 1, "a", "46546", 1, 20));
personTable.put(0,30,new Person(2, 1, "ab", "46546", 0, 30));
personTable.put(0,25,new Person(3, 1, "abc", "46546", 0, 25));
personTable.put(1,50,new Person(4, 1, "aef", "46546", 1, 50));
personTable.put(0,27,new Person(5, 1, "ade", "46546",0, 27));
personTable.put(1,29,new Person(6, 1, "acc", "46546", 1, 29));
personTable.put(0,33,new Person(7, 1, "add", "46546",0, 33));
personTable.put(1,66,new Person(8, 1, "afadsf", "46546", 1, 66));
//1,得到行集合
Map<Integer,Person> rowMap= personTable.row(0);
int maxAge= Collections.max(rowMap.keySet());
}
BiMap是一个一一映射,可以通过key得到value,也可以通过value得到key;private static void testBitMap() {
//双向map
BiMap<Integer,String> biMap=HashBiMap.create();
biMap.put(1,"hello");
biMap.put(2,"helloa");
biMap.put(3,"world");
biMap.put(4,"worldb");
biMap.put(5,"my");
biMap.put(6,"myc");
int value= biMap.inverse().get("my");
System.out.println("my --"+value);
}
ClassToInstanceMapClassToInstanceMap<Number> numberDefaults = MutableClassToInstanceMap.create();
numberDefaults.putInstance(Integer.class, Integer.valueOf(0));
private static void testClass() {
ClassToInstanceMap<Person> classToInstanceMap =MutableClassToInstanceMap.create();
Person person= new Person(1,20,"abc","46464",1,100);
classToInstanceMap.putInstance(Person.class,person);
// System.out.println("string:"+classToInstanceMap.getInstance(String.class));
// System.out.println("integer:" + classToInstanceMap.getInstance(Integer.class));
Person person1=classToInstanceMap.getInstance(Person.class);
}
3.4 谓词和筛选
谓词(Predicate)是用来筛选集合的;
谓词是一个简单的接口,只有一个方法返回布尔值,但是他是一个很令人惊讶的集合方法,当你结合collections2.filter方法使用,这个筛选方法返回原来的集合中满足这个谓词接口的元素;
举个例子来说:筛选出集合中的女人
public static void main(String[] args){Optional<ImmutableMultiset<Person>> optional=Optional.fromNullable(testPredict());if(optional.isPresent()){for(Person p:optional.get()){System.out.println("女人:"+p);}}System.out.println(optional.isPresent());}public static ImmutableMultiset<Person> testPredict(){List<Person> personList=Lists.newArrayList(new Person(1, 1, "a", "46546", 1, 20),new Person(2, 1, "ab", "46546", 0, 30),new Person(3, 1, "abc", "46546", 0, 25),new Person(4, 1, "aef", "46546", 1, 50),new Person(5, 1, "ade", "46546",0, 27),new Person(6, 1, "acc", "46546", 1, 29),new Person(7, 1, "add", "46546",0, 33));return ImmutableMultiset.copyOf(Collections2.filter(personList,new Predicate<Person>() {@Overridepublic boolean apply( Person input) {return input.getSex()==0;}}));}
Predicates含有一些内置的筛选方法,比如说 in ,and ,not等,根据实际情况选择使用。
3.5 功能和转换
转换一个集合为另外一个集合;
实例如下:
public static void main(String[] args){Optional<ImmutableMultiset<String>> optional=Optional.fromNullable(testTransform());if(optional.isPresent()){for(String p:optional.get()){System.out.println("名字:"+p);}}System.out.println(optional.isPresent());}public static ImmutableMultiset<String> testTransform(){List<Person> personList=Lists.newArrayList(new Person(1, 1, "a", "46546", 1, 20),new Person(2, 1, "ab", "46546", 0, 30),new Person(3, 1, "abc", "46546", 0, 25),new Person(4, 1, "aef", "46546", 1, 50),new Person(5, 1, "ade", "46546",0, 27),new Person(6, 1, "acc", "46546", 1, 29),new Person(7, 1, "add", "46546",0, 33));return ImmutableMultiset.copyOf(Lists.transform(personList,new Function<Person, String>() {@Overridepublic String apply( Person input) {return input.getName();}}));}
3.6 排序
是guava一份非常灵活的比较类,可以被用来操作,扩展,当作比较器,排序提供了集合排序的很多控制;
实例如下:
Lists.newArrayList(30, 20, 60, 80, 10);Ordering.natural().sortedCopy(numbers); //10,20,30,60,80Ordering.natural().reverse().sortedCopy(numbers); //80,60,30,20,10Ordering.natural().min(numbers); //10Ordering.natural().max(numbers); //80Lists.newArrayList(30, 20, 60, 80, null, 10);Ordering.natural().nullsLast().sortedCopy(numbers); //10, 20,30,60,80,nullOrdering.natural().nullsFirst().sortedCopy(numbers); //null,10,20,30,60,80 public static void testOrdering(){List<Person> personList=Lists.newArrayList(new Person(3, 1, "abc", "46546", 0, 25),new Person(2, 1, "ab", "46546", 0, 30),new Person(5, 1, "ade", "46546",0, 27),new Person(1, 1, "a", "46546", 1, 20),new Person(6, 1, "acc", "46546", 1, 29),new Person(4, 1, "aef", "46546", 1, 50),new Person(7, 1, "add", "46546",0, 33));Ordering<Person> byAge=new Ordering<Person>() {@Overridepublic int compare( Person left, Person right) {return right.getAge()-left.getAge();}};for(Person p: byAge.immutableSortedCopy(personList)){System.out.println(p);}}
原文地址:http://blog.csdn.net/songjinbin/article/details/50199649
- [Java工具集]Google Guava 常用功能
- Google Guava 常用功能
- Google的Java常用类库 Guava
- Google Guava 工具集简介-使用
- Google Guava 工具集__2__Cache 缓存使用
- google工具类guava
- Java开发工具集---Guava
- Google的guava,Java中集合的增强工具
- java-Google Guava
- Guava介绍 – Google的Java常用类库
- Google的Java常用类库 Guava资料
- Google Guava常用类库
- 【第三方类库】Java Guava , Google Guava
- Google Guava学习(6)-Guava集合工具 Multiset
- Google Guava学习(7)-Guava集合工具 Bimap接口
- Google Guava学习(8)-Guava集合工具 Table接口
- Google Guava学习(10)-Guava字符串工具Joiner
- Google Guava学习(10)-Guava字符串工具Spiltter
- 阿里系UTDID库生成唯一性ID分析
- 回调的概念
- caffe示例实现之11逻辑回归及其深化
- SQL
- opencv dft
- [Java工具集]Google Guava 常用功能
- 前端必读:浏览器内部工作原理
- Android 解决65535的限制 使用android-support-multidex解决Dex超出方法数的限制问题,让你的应用不再爆棚
- c函数调用过程原理及函数栈帧分析
- Codeforces 111C Petya and Spiders 题解&代码
- Android画图之抗锯齿
- JSONP
- 阿里云OSS存储开发(一)
- 【Git commit错误】 cant not commit a partial during a merge