Guava是一个Java编程语言的开源工具库,由Google开发和维护。它提供了许多实用的工具类和方法,用于简化Java编程中的常见任务,例如,集合(collections)操作、缓存(caching)操作、字符串处理(string processing)、并发编程(concurrency libraries)、I/O操作等等。Guava的目标是提高Java编程的生产力和代码质量,使开发人员能够更快地编写出高质量的代码。Guava的特点主要包括:
高效的集合工具类:Guava提供了许多高效的集合工具类,例如Immutable集合、Multiset、Multimap等等,可以大大简化集合操作的代码。
字符串处理工具类:Guava提供了许多字符串处理工具类,例如Splitter、Joiner、CaseFormat等等,可以方便地进行字符串的拆分、连接、格式化等操作。
并发编程工具类:Guava提供了许多并发编程工具类,例如ListenableFuture、RateLimiter、Monitor等等,可以方便地进行并发编程。
I/O操作工具类:Guava提供了许多I/O操作工具类,例如Files、ByteStreams、CharStreams等等,可以方便地进行文件读写、流操作等操作。
总之,Guava是一个非常实用的Java工具库,这些高质量的API可以使你的JAVA代码更加优雅,更加简洁,可以大大提高Java编程的效率和代码质量,下面我们就开启优雅Java编程学习之旅!
基本工具类:让使用Java语言更令人愉悦。
二. 集合类:集合类库是 Guava 对 JDK 集合类的扩展, 这是 Guava 项目最完善和为人所知的部分。
三. 缓存: 本地缓存,可以很方便的操作缓存对象,并且支持各种缓存失效行为模式。
四. Functional idioms(函数式): 简洁, Guava实现了Java的函数式编程,可以显著简化代码。
五. Concurrency(并发):强大,简单的抽象,让我们更容易实现简单正确的并发性代码。
<dependency>
<groupId>com.google.guavagroupId>
<artifactId>guavaartifactId>
<version>31.1-jreversion>
<version>31.1-androidversion>
dependency>
接下来我们主要对比原生和Guava进行操作集合的效果,从而体现出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>>>();
我们演示一下在日常的开发过程中如何进行创建LinkedList的方式。
List<Person> personList= Lists.newLinkedList();
我们演示一下在日常的开发过程中如何进行创建 HashSet的方式。
Set<Person> personSet= Sets.newHashSet();
我们演示一下在日常的开发过程中如何进行创建 HashMap的方式。
Map<String,Person> personMap= Maps.newHashMap();
我们演示一下在日常的开发过程中如何进行创建Array的方式。
Integer[] intArrays= ObjectArrays.newArray(Integer.class,10);
我们演示一下在日常的开发过程中如何进行创建复杂集合泛型的方式。
Map<String, Map<String, String>> map = Maps.newHashMap();
List<List<Map<String, String>>> list = Lists.newArrayList();
初始化对应的初始元素信息方案案例:
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");
简化泛型对象集合的初始化
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));
很大一部分是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]
实用Guava创建一个不可变的Set集合。
ImmutableSet<Integer> numbers = ImmutableSet.of(10, 20, 30, 40, 50);
使用Guava拷贝一个集合,实用的是copyOf方法。
ImmutableSet<Integer> another = mmutableSet.copyOf(numbers);
使用Builder方法,进行构建Set集合信息。
ImmutableSet<Integer> numbers2 = ImmutableSet.<Integer>builder().addAll(numbers).add(60) .add(70).add(80).build();
Guava API 提供了有用的新的集合类型,协同已经存在的java集合工作的很好。主要集中于MultiMap, MultiSet, Table, BiMap, ClassToInstanceMap。
一种key可以重复的map,子类有ListMultimap和SetMultimap,对应的通过key分别得到list和set。
创建对应的ArrayListMultimap集合对象
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,可以等价于:Map
采用工厂方法建立Table对象信息集合,如下所示。
Table<Integer,Integer,Person> personTable=HashBasedTable.create();
上面我们采用的是HashMap为基础的Table数据模型。
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));
}
Map<Integer,Person> rowMap= personTable.row(0);
int maxAge= Collections.max(rowMap.keySet());
BiMap是一个一一映射,可以通过key得到value,也可以通过value得到key;
BiMap<Integer,String> biMap = HashBiMap.create();
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);
}
有的时候,你的map的key并不是一种类型,他们是很多类型,你想通过映射他们得到这种类型,guava提供了ClassToInstanceMap满足了这个目的。
除了继承自Map接口,ClassToInstaceMap提供了方法 T getInstance(Class) 和 T putInstance(Class, T),消除了强制类型转换。该类有一个简单类型的参数,通常称为B,代表了map控制的上层绑定,例如:
ClassToInstanceMap<Number> numberDefaults = MutableClassToInstanceMap.create();
numberDefaults.putInstance(Integer.class, Integer.valueOf(0));
从技术上来说,ClassToInstanceMap 实现了Map
guava提供了有用的实现, MutableClassToInstanceMap 和 ImmutableClassToInstanceMap.
重点:像其他的Map
,ClassToInstanceMap 含有的原生类型的项目,一个原生类型和他的相应的包装类可以映射到不同的值;
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);
}
谓词是一个简单的接口,只有一个方法返回布尔值,但是他是一个很令人惊讶的集合方法,当你结合collections2.filter方法使用,这个筛选方法返回原来的集合中满足这个谓词接口的元素。
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>() {
@Override
public boolean apply( Person input) {
return input.getSex()==0;
}
}));
}
Optional<ImmutableMultiset<Person>> optional=Optional.fromNullable(testPredict());
if(optional.isPresent()){
for(Person p:optional.get()){
System.out.println("女人:"+p);
}
}
Predicates含有一些内置的筛选方法,比如说 in ,and ,not等,根据实际情况选择使用。
主要将转换一个集合为另外一个集合;
实例如下:
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>() {
@Override
public String apply( Person input) {
return input.getName();
}
}));
}
Optional<ImmutableMultiset<String>> optional=Optional.fromNullable(testTransform());
if(optional.isPresent()){
for(String p:optional.get()){
System.out.println("名字:"+p);
}
}
Ordering是guava一份非常灵活的比较类,可以被用来操作,扩展,当作比较器,排序提供了集合排序的很多控制。
Lists.newArrayList(30, 20, 60, 80, 10);
//10,20,30,60,80
Ordering.natural().sortedCopy(Lists.newArrayList());
//10,20,30,60,80
//80,60,30,20,10
Ordering.natural().reverse().sortedCopy(numbers);
Ordering.natural().min(numbers); //10
Ordering.natural().max(numbers); //80
// 队尾插入空元素
Ordering.natural().nullsLast().sortedCopy(numbers); //10, 20,30,60,80,null
// 队头插入空元素
Ordering.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>() {
@Override
public int compare( Person left, Person right) {
return right.getAge() - left.getAge();
}
};
for(Person p: byAge.immutableSortedCopy(personList)){
System.out.println(p);
}
}