guava
guava是什么
Guava是Java项目广泛第三方库,其中包括:集合 、缓存 、原生类型支持 、并发库 、通用注解 、字符串处理 、I/O 等等。 所有这些工具每天都在被java工程b师应用在业务服务中。
集合
再jdk1.7之前,原生jdk对集合操作并不友好,使用guava的集合很大程度上方便了我们对集合的操作。
集合的创建
public static void main(String[] args) {
List<String> list = Lists.newArrayList();
List<String> list1 = Lists.newArrayList("1","3","4");
List<String> list2 = Lists.newArrayList(list1);
Set<String> set = Sets.newHashSet();
Map<String, String> map = Maps.newHashMap();
//创建不计算加载因子的集合大小
Map<String, String> map1 = Maps.newHashMapWithExpectedSize(88);
}
不可变集合
举出部分例子,api有很多
public static void main(String[] args) {
ImmutableList<String> list = ImmutableList.of("1", "2");
ImmutableList<Object> copyList = ImmutableList.copyOf(new ArrayList<>());
ImmutableSet<String> set = ImmutableSet.of("3", "4");
ImmutableMap<String, String> map = ImmutableMap.of("a", "A", "b", "B");
ImmutableMap<Object, Object> hashmap = ImmutableMap.copyOf(new HashMap<>());
}
新集合类型
Multiset
类似jdk set集合的一种变体,这个set集合可以获取重复元素的个数,而jdk的set集合重复会直接覆盖,不会记录,很方便获取集合中元素的个数。
public static void main(String[] args) {
//此时也是使用guava 很方便吧,直接可以复制,不用在,泛型使用的也更加简单了
// List<String> strings = Arrays.asList("a", "b", "c", "d", "e", "f", "a", "c", "d", "a");
//原始方法求集合中元素的个数
List<String> strings = Lists.newArrayList("a", "b", "c", "d", "e", "f", "a", "c", "d", "a");
Map<String, Integer> countMap = Maps.newHashMap();
for (String string : strings) {
if (countMap.containsKey(string)){
Integer count = countMap.get(string);
countMap.put(string,++count);
}else {
countMap.put(string,1);
}
}
System.out.println(new Gson().toJson(countMap));
//使用guava的新集合
Multiset multiset = HashMultiset.create();
//求交集
multiset.addAll(strings);
System.out.println("新集合元素:"+multiset);
System.out.println("a的次数:"+ multiset.count("a"));
System.out.println("c的次数:"+multiset.count("c"));
System.out.println("f的次数:"+multiset.count("f"));
//还可以自定义设置参数
multiset.setCount("a",1000);
System.out.println(multiset);
System.out.println("a的次数:"+ multiset.count("a"));
}
}
reslut:
{
"a":3,"b":1,"c":2,"d":2,"e":1,"f":1}
新集合元素:[a x 3, b, c x 2, d x 2, e, f]
a的次数:3
c的次数:2
f的次数:1
[a x 1000, b, c x 2, d x 2, e, f]
a的次数:1000
ListMultimap
集合分组,类似jdk map的一种,主要用于value是list的map集合。
public static void main(String[] args) {
//list转map,分别计算出3年级与2年级的学生信息
//传统做法
Student student = new Student(19,"王强" , 1, 3);
Student student1 = new Student(18,"张强" , 1, 2);
Student student2 = new Student(18,"李静" , 2, 2);
Student student3 = new Student(19,"王萍" , 1, 3);
List<Student> strings = Lists.newArrayList(student,student1,student2,student3);
Map<Integer, List<Student>> studentMap = Maps.newHashMap();
for (Student string : strings) {
if (studentMap.containsKey(string.getGrade())){
List<Student> students = studentMap.get(string.getGrade());
students.add(string);
}else {
List<Student> objects = Lists.newArrayList();
objects.add(string);
studentMap.put(string.getGrade(),objects);
}
}
System.out.println(new Gson().toJson(studentMap));
System.out.println("****************************************************guava分割**************************************************************");
//第一个泛型就是分组的key 第二个泛型就是集合的类型
ListMultimap<Integer, Student> build = MultimapBuilder.treeKeys().arrayListValues().build();
for (Student string : strings) {
//一行代码就搞定
build.put(string.getGrade(),string);
}
//转成map同上面相同
System.out.println("转map:"+new Gson().toJson(build.asMap()));
System.out.println("班级2集合:"+new Gson().toJson(build.get(2)));
System.out.println("班级3集合:"+new Gson().toJson(build.get(3)));
//删除班级2的王强
boolean remove = build.remove(2, student1);
System.out.println("删除班级2的张强转map:"+new Gson().toJson(build.asMap()));
//删除班级3的所有人
List<Student> students = build.removeAll(3);
System.out.println("删除班级3的所有人转map:"+new Gson().toJson(build.asMap()));
}
result
{
"2":[{
"age":18,"name":"张强","sex":1,"grade":2},{
"age":18,"name":"李静","sex":2,"grade":2}],"3":[{
"age":19,"name":"王强","sex":1,"grade":3},{
"age":19,"name":"王萍","sex":1,"grade":3}]}
****************************************************guava分割**************************************************************
转map:{
"2":[{
"age":18,"name":"张强","sex":1,"grade":2},{
"age":18,"name":"李静","sex":2,"grade":2}],"3":[{
"age":19,"name":"王强","sex":1,"grade":3},{
"age":19,"name":"王萍","sex":1,"grade":3}]}
班级2集合:[{
"age":18,"name":"张强","sex":1,"grade":2},{
"age":18,"name":"李静","sex":2,"grade":2}]
班级3集合:[{
"age":19,"name":"王强","sex":1,"grade":3},{
"age":19,"name":"王萍","sex":1,"grade":3}]
删除班级2的张强转map:{
"2":[{
"age":18,"name":"李静","sex":2,"grade":2}],"3":[{
"age":19,"name":"王强","sex":1,"grade":3},{
"age":19,"name":"王萍","sex":1,"grade":3}]}
删除班级3的所有人转map:{
"2":[{
"age":18,"name":"李静","sex":2,"grade":2}]}
ArrayListMultimap
同上
public static void main(String[] args) {
Multimap<String, String> objectObjectArrayListMultimap = ArrayListMultimap.create();
objectObjectArrayListMultimap.put("a","a");
objectObjectArrayListMultimap.put("a","b");
objectObjectArrayListMultimap.put("v","c");
objectObjectArrayListMultimap.put("v","a");
objectObjectArrayListMultimap.put("v","b");
System.out.println(new Gson().toJson(objectObjectArrayListMultimap.asMap()));
}
结果
{
"a":["a","b"],"v":["c","a","b"]}
BiMap
类似hashmap,但是这个集合可以反转。可以通过key取value,也可以通过value取key。不需要我们去维护两个map。注意,value不能重复,否则会报错。
public static void main(String[] args) {
BiMap<String,String> biMap = HashBiMap.create();
biMap.put("1","一");
System.out.println("根据key取value:"+biMap.get("1"));
BiMap<String, String> inverse = biMap.inverse();
System.out.println("根据value取key:"+inverse.get("一"));
HashMap<String, String> hashMap = Maps.newHashMap();
hashMap.put("张","zhang");
BiMap<String, String> hashBiMap = HashBiMap.create(hashMap);
System.out.println("根据key取value:"+hashBiMap.get("张"));
BiMap<String, String> stringBiMap = hashBiMap.inverse();
System.out.println("根据value取key:"+stringBiMap.get("zhang"));
}
结果:
根据key取value:一
根据value取key:1
根据key取value:zhang
根据value取key:张
table
提供两个维度去查询我们的数据
public static void main(String[] args) {
Table<String, String, String> table = HashBasedTable.create();
table.put("a","b","ab");
System.out.println(table.get("a","b"));
System.out.println(table.column("b").get("a"));
}
集合的排序
public static void main(String[] args) {
/**
* 创建排序器
*/
//做自然排序
Ordering ordering = Ordering.natural();
//把给定的Comparator转化为排序器
Ordering<String> from = Ordering.from((a,b)->a.length()-b.length());
//通过构造方法指定排序
Ordering<String> objectOrdering = new Ordering<String>() {
@Override
public int compare(String a, String b) {
return a.length()-b.length();
}
};
/**
* 排序器的运用
*/
List<String> strings = Lists.newArrayList("a", "b", "d", "f", "c");
boolean ordered = ordering.isOrdered(strings);
System.out.println("是否执行了自然排序,执行了为true,没有执行为false:"+ordered);
List list = ordering.sortedCopy(strings);
System.out.println("自然排序:"+list);
//参数为排序后的集合
boolean ordered1 = ordering.isOrdered(list);
System.out.println("是否执行了自然排序,执行了为true,没有执行为false:"+ordered1);
//空排序到后面,取反
Ordering reverse = ordering.nullsLast().reverse();
List list1 = reverse.sortedCopy(list);
System.out.println("是否取反:"+list1);
//如何是我们代码更加优雅,例如我们只想对某个对象的一个属性进行排序,
//又不想使用compare接口去实现,为了是代码更加优雅,我们可以这样做
class Student{
String name;
String addr;
int age;
public Student(String name, String addr, int age) {
this.name = name;
this.addr = addr;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
List<Student> students = Lists.newArrayList(new Student("zhang", "shanghai", 13), new Student("wang", "beijing", 16), new Student("li", "guangzhou", 14));
//这句代码的意思是对对象的年龄进行排序,以自然顺序进行排序
Ordering<Student> iter = Ordering.natural().nullsLast().onResultOf(a->a.getAge());
List<Student> sortedCopy= iter.sortedCopy(students);
System.out.println("排序后的student集合:"+ JSON.toJSONString(sortedCopy));
}
结果
是否执行了自然排序,执行了为true,没有执行为false:false
自然排序:[a, b, c, d, f]
是否执行了自然排序,执行了为true,没有执行为false:true
是否取反:[f, d, c, b, a]
排序后的student集合:[{
"addr":"shanghai","age":13,"name":"zhang"},{
"addr":"guangzhou","age":14,"name":"li"},{
"addr":"beijing","age":16,"name":"wang"}]
集合与字符串操作
Joiner
集合分割为字符串,并忽略空
public static void main(String[] args) {
List<String> strings = Lists.newArrayList("java", "python", "c", "c++", "golang", "javascript", "php");
System.out.println(Joiner.on("; ").skipNulls().join(strings));
}
Splitter
字符串转集合
方法 | 说明 |
---|---|
omitEmptyStrings() | 从结果中自动忽略空字符串 |
trimResults() | 移除结果字符串的前导空白和尾部空白 |
trimResults(CharMatcher) | 给定匹配器,移除结果字符串的前导匹配字符和尾部匹配字符 |
limit(int) | 限制拆分出的字符串数量 |
public static void main(String[] args) {
String s = "a,b,c,d,";
Iterable<String> split = Splitter.on(',').trimResults().omitEmptyStrings().split(s);
System.out.println(JSON.toJSONString(Lists.newArrayList(split)));
}
集合的分割
按照指定大小分割集合
List<String> strings = Lists.newArrayList("a", "b", "c", "d", "e", "f", "g");
List<List<String>> partition = Lists.partition(strings, 3);
System.out.println(JSON.toJSONString(partition));
集合的过滤filter、转换map、list->map
集合转换,类似于jdk1.8或js的map函数
public static void main(String[] args) {
List<String> strings = Lists.newArrayList("a", "b", "c", "d", "e", "f", "g");
List<String> transform = Lists.transform(strings,s->s.toUpperCase());
System.out.println(JSON.toJSONString(transform));
}
集合的过滤,保留字符串长度大于4的集合,以后讲jdk1.8都会讲到
public static void main(String[] args) {
List<String> strings = Lists.newArrayList("java", "python", "c", "c++", "golang", "javascript", "php");
Collection<String> filter = Collections2.filter(strings, s -> s.length() >= 4);
ArrayList<String> strings1 = Lists.newArrayList(filter);
System.out.println(strings1);
}
有时我们会有这样的需求,有一个已知一个list,里面存对象,我们需要根据id来获取这个id的对象,我们根据id存入map来处理逻辑会更加方便。
注意:id冲突会报错
public static void main(String[] args) {
Student student = new Student(1, "wang");
Student student1 = new Student(2, "wang");
Student student2 = new Student(3, "wang");
List<Student> list = Lists.newArrayList();
list.add(student);
list.add(student1);
list.add(student2);
Map<Object, Object> objectObjectHashMap = Maps.newHashMap();
Map<Long, Student> longStudentImmutableMap = Maps.uniqueIndex(list, s -> s.getId());
}