缘起
为什么要使用Guava呢?因为在几年前就是用过Guava的部分功能,当时有一个项目需要通过缓存来提升部分功能的性能,对本地应用缓存和分布式应用缓存进行了相关的调研,在调研本地应用缓存的时候,第一次看到了Guava
这个词,在本地缓存中,Guava与Caffeine、Ehcache等技术都各有独特的应用场景。
Guava是开源的、轻量级的、缓存算法采用的是LRU、JDK版本不低于1.6、不支持数据的持久化、无集群解决方案、没有性能监控功能等特点。
缓存对于Guava来说,只是众多特色功能中的冰山一角,Guava还提供了很多被广泛应用的核心库。
简介
Guava,中文是石榴的意思,Guava项目,是基于java的Google的开源的工具类库,Guava工程包含了若干被Google的 Java项目广泛依赖 的核心库,例如:
- 集合 [collections]
- 缓存 [caching]
- 原生类型支持 [primitives support]
- 并发库 [concurrency libraries]
- 通用注解 [common annotations]
- 字符串处理 [string processing]
- I/O 等等。
项目中为什么要选择Guava?
借用广为流传的回答如下所示:
- Guava是Java API蛋糕上的冰激凌(精华)
- 高效设计良好的API
- 被Google的开发者设计,实现和使用
- 遵循高效的Java这本书的好的语法实践
- 使代码更可读、简洁、简单
- 使用Java1.5的特性
- 流行的API、动态的开发
- 提供了大量相关的应用类、集合、多线程、比较、字符串、输入输出、缓存、网络、原生类型、数学、反射等等
- 100%的单元测试,被很多的项目使用,帮助开发者专注业务逻辑而不是写应用类
- 节省时间、资源,提高生产力
- 目的是为基本的Java特征提供开源代码的支持,而不是自己再写一个
- Apache Common库是一个很好地成熟的库,但是不支持泛型,Apache对早起的Java版本很有用(1.5之前)
- Java7,Java8等最新的Java支持一些Guava的API
在项目开发中适当的场景灵活运用Guava,可使我们省去复杂的数据处理,代码简洁易用,不易出错,代码可读性、健壮性增强,让我们有更多时间专注业务的处理。
Guava处理字符串、List、map
在实际的项目开发过程中,经过需要对字符串与List、字符串与map进行互相的转换,由于缺乏稳定的、易用的库支持,导致一个简单地需求,需要些很多的代码来自我实现,在调用的过程中,有可能出现异常或者性能问题。
例如:将集合list转换成一个用逗号分隔的字符串,需要自我实现,代码如下:
/**
* 把list转换为一个用逗号分隔的字符串
*
* @param list list对象
* @return
*/
public static String listToString(List list){
if (list == null || list.size() ==0) {
return null;
}
StringBuffer sb = new StringBuffer();
for (int i = 0; i < list.size(); i++) {
if (i < list.size()-1) {
sb.append(list.get(i)+",");
}else {
sb.append(list.get(i));
}
}
return sb.toString();
}
Guava提供了非常简洁、高效的转换方法,具体如下:
case 1:List转换为String
@Test
public void joinTest(){
List<String> names = Lists.newArrayList("John", "Jane", "Adam", "Tom");
String result = Joiner.on(",").join(names);
assertEquals(result, "John,Jane,Adam,Tom");
}
case 2:Map转换为String
@Test
public void convertMapToString() {
Map<String, Integer> salary = Maps.newHashMap();
salary.put("张三", 12300);
salary.put("李四", 1500);
String result = Joiner.on(" , ").withKeyValueSeparator(" == ").join(salary);
assertEquals(result, "李四 == 1500 , 张三 == 12300");
}
case 3:list转换为String,剔除null
@Test
public void convertListToStringAndSkipNull() {
List<String> names = Lists.newArrayList("John", null, "Jane", "Adam", "Tom");
String result = Joiner.on(",").skipNulls().join(names);
assertEquals(result, "John,Jane,Adam,Tom");
}
case 4:List转换为String,并将值为null的编程其他值
public void whenUseForNull_thenUsed() {
List<String> names = Lists.newArrayList("John", null, "Jane", "Adam", "Tom");
String result = Joiner.on(",").useForNull("nameless").join(names);
assertEquals(result, "John,nameless,Jane,Adam,Tom");
}
case 5: String转换为List
public void createListFromString() {
String input = "lisi - zhangsan - wangwu";
List<String> result = Splitter.on("-").trimResults().splitToList(input);
System.out.println(result);
}
case 6: String转换为Map
public void createMapFromString() {
String input = "John=first,Adam=second";
Map<String, String> result = Splitter.on(",").withKeyValueSeparator("=").split(input);
assertEquals("first", result.get("John"));
assertEquals("second", result.get("Adam"));
}
case 7: 多个字符进行分隔
public void splitStringOnMultipleSeparator() {
String input = "apple.banana,,orange,,.";
List<String> result = Splitter.onPattern("[.|,]").omitEmptyStrings().splitToList(input);
System.out.println(result);
}
case 8: 每隔多个字符进行分割
public void splitStringOnSpecificLength() {
String input = "Hello world !!";
List<String> result = Splitter.fixedLength(3).splitToList(input);
System.out.println(result);
}
case 9: 限制分割多少字后停止
public void limitSplitting() {
String input = "a,b,c,d,e";
List<String> result = Splitter.on(",").limit(4).splitToList(input);
assertEquals(4, result.size());
System.out.println(result);
}