赞
踩
工具类将经常用的一些方法进行了封装,遇到相同的场景时不需要重复造轮子,从而大量节省开发人员时间和提高工作效率,Guava就是谷歌发布的高效率的方法的工具包。Guava的优势:
Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException)本质上是一个包含有可选值的包装类,这意味着 Optional 类既可以含有对象也可以为空。Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。
Optional 类的引入很好的解决空指针异常。
// Optional<T>表示可能为null的T类型引用,但Optional从不会包含null值引用
Optional<Integer> possible = Optional.of(5);
System.out.println("is present:" + possible.isPresent()); // returns true
System.out.println("possible value:" + possible.get()); // returns 5
当一个对象中的字段可以为null时,实现Object.equals方法会很痛苦,因为不得不分别对它们进行null检查,使用Objects.equal帮助你执行null敏感的equals判断,从而避免抛出NullPointerException。
// 使用Objects.equal帮助你执行null敏感的equals判断,从而避免抛出NullPointerException
System.out.println(Objects.equal("a", "a")); // returns true
System.out.println(Objects.equal(null, "a")); // returns false
System.out.println(Objects.equal("a", null)); // returns false
System.out.println(Objects.equal(null, null)); // returns true
Objects.hashCode方法可以快速重写Java对象的hashCode方法,基于对象的指定字段来计算散列值,避免自己手动生成。
@Test public int test() { Person person = new Person("zhao", "si", 51); Person pre = new Person("zhang", "fei", 86); Person back = new Person("zhang", "fei", 86); // Guava的Objects.hashCode(Object...)会对传入的字段序列计算出合理的、顺序敏感的散列值 // 可以使用Objects.hashCode(field1, field2, …, fieldn)来代替手动计算散列值 System.out.println("person hash code:" + person.hashCode());// person hash code:-703024680 System.out.println("pre hash code:" + pre.hashCode());// pre hash code:-320142505 System.out.println("back hash code:" + back.hashCode());// back hash code:-320142505 } @Override public int hashCode() { return Objects.hashCode(lastName, firstName, zipCode); }
MoreObjects.toStringHelper
可以轻松编写有用的toString方法,主要用于Java对象的字段打印显示。
// 使用 MoreObjects.toStringHelper可以轻松编写有用的toString方法
// Returns "ClassName{x=1}" GuavaTest{x=1}
System.out.println(MoreObjects.toStringHelper(this).add("x", 1));
// Returns "MyObject{x=1}"
System.out.println(MoreObjects.toStringHelper("MyObject").add("x", 1));
ComparisonChain
执行一种懒比较:它执行比较操作直至发现非零的结果,在那之后的比较输入将被忽略。该工具类方便我们快速实现比较的功能。
@Override public int test() { Person pre = new Person("zhang", "fei", 86); Person back = new Person("zhang", "fei", 86); int compareRes = pre.compareTo(back); System.out.println("compare res:" + compareRes); // compare res:0 System.out.println("equals res:" + pre.equals(back));// equals res:true System.out.println("equals res:" + pre.equals(person));// equals res:false } @Override public int compareTo(@NotNull Person o) { return ComparisonChain.start().compare(getFirstName(), o.getFirstName()) .compare(getLastName(), o.getLastName()) .compare(getZipCode(), o.getZipCode()) .result(); }
// Preconditions类中提供了若干前置条件判断的实用方法
int i = 5, j = 3;
Preconditions.checkArgument(i >= 0, "Argument was %s but expected nonnegative", i);
Preconditions.checkArgument(i > j, "Expected i < j, but %s > %s", i, j);
不可变对象有很多优点,包括:
ImmutableSet<String> COLOR_NAMES = ImmutableSet.of("red", "orange", "yellow", "green", "blue", "purple");
ImmutableSet<String> set = ImmutableSet.of("a", "b", "c", "a");
System.out.println(ImmutableSet.copyOf(list));// [a, b, c]
System.out.println(set.asList());// [a, b, c]
System.out.println(COLOR_NAMES.asList());// [red, orange, yellow, green, blue, purple]
ImmutableList<String> list = ImmutableList.of("a", "b", "c", "a");
System.out.println(list.asList());// [a, b, c, a]
同一个Key可放多个值,值不可以重复。
// 替换Map<K,Set<V>>结构
HashMultimap<String, String> multimap = HashMultimap.create();
multimap.put("key1", "value");
multimap.put("key1", "value1");
multimap.put("key1", "value");
System.out.println(multimap.get("key1"));// [value, value1]
ArrayListMultimap
可用于替换Map<K,List<V>>
和Map<K,Set<V>>
结构,适用于键为单个元素,值为集合的场景,值可以重复。
// 替换Map<K,List<V>>结构
ArrayListMultimap<String, String> listMultimap = ArrayListMultimap.create();
listMultimap.put("key", "value-1");
listMultimap.put("key", "value-2");
listMultimap.put("key", "value-3");
System.out.println(listMultimap.get("key"));// [value-1, value-2, value-3]
HashMultiset
可以多添加相等的元素,比较适用于键为元素,值为计数的场景,类似于没有元素顺序限制的ArrayList<E>
。
// 1.没有元素顺序限制的ArrayList<E> 2.Map<E, Integer>,键为元素,值为计数
HashMultiset<String> counts = HashMultiset.create();
counts.add("alibaba");
counts.add("ant", 5);
System.out.println(counts.count("alibaba"));// 1
System.out.println(counts.count("ant")); // 5
例如当我们去统计一个字符串数组当中各个字符串出现的次数,两种实现方式如下,可以看出Guava工具的简洁性。
@Test public void count(){ String[] array = {"A", "B", "C","A", "B", "C", "D", "F","D", "F", "G", "U"}; List<String> strs = Lists.asList("A", array); // 1.常规方式实现计数 HashMap<String,Integer> countHashMap = Maps.newHashMap(); for (String s : strs) { if (java.util.Objects.isNull(countHashMap.get(s))) { countHashMap.put(s, 1); }else{ countHashMap.put(s, countHashMap.get(s) + 1); } } // {A=3, B=2, C=2, D=2, U=1, F=2, G=1} System.out.println(countHashMap); // 2.Guava方式实现计数 HashMultiset<String> countHashMultiset = HashMultiset.create(); countHashMultiset.addAll(strs); // [A x 3, B x 2, C x 2, D x 2, U, F x 2, G] System.out.println(countHashMultiset); }
// 实现键值对的双向映射需要维护两个单独的map,并保持它们间的同步
BiMap<String, Integer> userId = HashBiMap.create();
userId.put("zhan", 2207);
userId.put("zhao", 3312);
System.out.println(userId.get("zhao") + ":" + userId.inverse().get(3312));// 3312:zhao
System.out.println(userId.get("zhan") + ":" + userId.inverse().get(2207));// 2207:zhan
你可能会遇到使用多个键做索引的时候可能会用类似Map<FirstName, Map<LastName, Person>>
的实现方式,这种方式不但很丑陋,而且使用上也不友好。因此Guava提供了Table新结构来解决这种场景。
Table<String, String, Integer> table = HashBasedTable.create(); table.put("A", "B", 1); table.put("A", "C", 2); table.put("B", "D", 3); for (Cell<String, String, Integer> cell : table.cellSet()) { System.out.println(cell.getRowKey() + " " + cell.getColumnKey() + " " + cell.getValue()); } /* print res: * A B 1 * A C 2 * B D 3 */ Map<String, Map<String, Integer>> map = table.rowMap(); for (String row : map.keySet()) { Map<String, Integer> tmp = map.get(row); for (Entry<String, Integer> pair : tmp.entrySet()) { System.out.println(row + " " + pair.getKey() + " " + pair.getValue()); } }
开发过程中集合初始化过程是必不可少的,你不会一直都是new一个新的对象吧,试试下面这种方式感觉会更棒。
/*集合初始化方式*/
List<String> theseElements = Lists.newArrayList("alpha", "beta", "gamma");
List<String> exactly = Lists.newArrayListWithCapacity(4);
List<String> approx = Lists.newArrayListWithExpectedSize(4);
Set<String> approxSet = Sets.newHashSetWithExpectedSize(4);
List<Integer> countUp = Ints.asList(1, 2, 3, 4, 5);
List<Integer> countDown = Lists.reverse(countUp);
List<List<Integer>> parts = Lists.partition(countUp, 2);
System.out.println(countDown); // {5, 4, 3, 2, 1}
System.out.println(parts); //{{1,2}, {3,4}, {5}}
针对于Set集合结构,可能会存在求两个集合相同元素的场景或者求两个集合的所有组合,这不就是求交集和笛卡尔积嘛,Guava也给我们提供了快速方法可以参考一手
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。