http://macrochen.iteye.com/blog/737058
?
参考:?
http://codemunchies.com/2009/10/beautiful-code-with-google-collections-guava-and-static-imports-part-1/(2,3,4)?
http://blog.publicobject.com?
更多用法参考http://ajoo.iteye.com/category/119082?
以前这么用:?
Java代码?
?
- Map<String,?Map<Long,?List<String>>>?map?=?new?HashMap<String,?Map<Long,List<String>>>();??
现在这么用(JDK7将实现该功能):?
Java代码?
?
- Map<String,?Map<Long,?List<String>>>?map?=?Maps.newHashMap();??
针对不可变集合:?
以前这么用:?
Java代码?
?
- List<String>?list?=?new?ArrayList<String>();??
- list.add("a");??
- list.add("b");??
- list.add("c");??
- list.add("d");??
现在Guava这么用:?
Java代码?
?
- ImmutableList<String>?of?=?ImmutableList.of("a",?"b",?"c",?"d");??
- ImmutableMap<String,String>?map?=?ImmutableMap.of("key1",?"value1",?"key2",?"value2");??
文本文件读取现在Guava这么用?
Java代码?
?
- File?file?=?new?File(getClass().getResource("/test.txt").getFile());??
- List<String>?lines?=?null;??
- try?{??
- lines?=?Files.readLines(file,?Charsets.UTF_8);??
- }?catch?(IOException?e)?{??
- e.printStackTrace();??
- }??
基本类型比较, 现在Guava这么用:?
Java代码?
?
- int?compare?=?Ints.compare(a,?b);??
Guava中CharMatcher的用法:?
Java代码?
?
- assertEquals("89983",?CharMatcher.DIGIT.retainFrom("some?text?89983?and?more"))??
- assertEquals("some?text??and?more",?CharMatcher.DIGIT.removeFrom("some?text?89983?and?more"))??
Guava中Joiner的用法:?
Java代码?
?
- int[]?numbers?=?{?1,?2,?3,?4,?5?};??
- String?numbersAsString?=?Joiner.on(";").join(Ints.asList(numbers));??
另一种写法:?
Java代码?
?
- String?numbersAsStringDirectly?=?Ints.join(";",?numbers);??
Guava中Splitter的用法:?
Java代码?
?
- Iterable?split?=?Splitter.on(",").split(numbsAsString);??
对于这样的字符串进行切分:?
Java代码?
?
- String?testString?=?"foo?,?what,,,more,";??
- Iterable<String>?split?=?Splitter.on(",").omitEmptyStrings().trimResults().split(testString);??
Ints中一些用法:?
Java代码?
?
- int[]?array?=?{?1,?2,?3,?4,?5?};??
- int?a?=?4;??
- boolean?contains?=?Ints.contains(array,?a);??
- int?indexOf?=?Ints.indexOf(array,?a);??
- int?max?=?Ints.max(array);??
- int?min?=?Ints.min(array);??
- int[]?concat?=?Ints.concat(array,?array2);??
集合?
set的交集, 并集, 差集的用法(http://publicobject.com/2008/08/coding-in-small-with-google-collections.html)?
Java代码?
?
- HashSet?setA?=?newHashSet(1,?2,?3,?4,?5);??
- HashSet?setB?=?newHashSet(4,?5,?6,?7,?8);??
- ???
- SetView?union?=?Sets.union(setA,?setB);??
- System.out.println("union:");??
- for?(Integer?integer?:?union)??
- ????System.out.println(integer);?????????
- ???
- SetView?difference?=?Sets.difference(setA,?setB);??
- System.out.println("difference:");??
- for?(Integer?integer?:?difference)??
- ????System.out.println(integer);????????
- ???
- SetView?intersection?=?Sets.intersection(setA,?setB);??
- System.out.println("intersection:");??
- for?(Integer?integer?:?intersection)??
- ????System.out.println(integer);??
针对Map的用法:?
Java代码?
?
- MapDifference?differenceMap?=?Maps.difference(mapA,?mapB);??
- ??
- differenceMap.areEqual();??
- Map?entriesDiffering?=?differenceMap.entriesDiffering();??
- Map?entriesOnlyOnLeft?=?differenceMap.entriesOnlyOnLeft();??
- Map?entriesOnlyOnRight?=?differenceMap.entriesOnlyOnRight();??
- Map?entriesInCommon?=?differenceMap.entriesInCommon();??
验证与条件检查?
原来的写法:?
Java代码?
?
- if?(count?<=?0)?{???????????????????????????????????????????????????????????????????????????????????????????
- ????throw?new?IllegalArgumentException("must?be?positive:?"?+?count);?????????
- }????
- ??????
????????????
Guava的写法(Jakarta Commons中有类似的方法):?
Java代码?
?
- Preconditions.checkArgument(count?>?0,?"must?be?positive:?%s",?count);??
一个更酷的用法:?
Java代码?
?
- public?PostExample(final?String?title,?final?Date?date,?final?String?author)?{??
- ????this.title?=?checkNotNull(title);??
- ????this.date?=?checkNotNull(date);??
- ????this.author?=?checkNotNull(author);??
- }??
如果一个key对应多个value的Map, 你会怎么处理? 如果还在使用Map<K, List<V>>的话, 你就out了?
使用MultiMap吧:?
Java代码?
?
- Multimap<Person,?BlogPost>?multimap?=?ArrayListMultimap.create();??
Multimap的另一个使用场景:?
比如有一个文章数据的map:?
Java代码?
?
- List<Map<String,?String>>?listOfMaps?=?mapOf("type",?"blog",?"id",?"292",?"author",?"john");??
如果要按照type分组生成一个List?
Java代码?
?
- Multimap<String,?Map<String,?String>>?partitionedMap?=?Multimaps.index(?????
- ????????????????listOfMaps,?????????????????????????????????????????????????????????????????????????????????????????
- ????????????????new?Function<Map<String,?String>,?String>()?{???????????????????????????????????
- ????????????????????public?String?apply(final?Map<String,?String>?from)?{??????????????????????
- ????????????????????????return?from.get("type");???????????????????????????????????????????????????????????????
- ????????????????????}?????????????????????????????????????????????????????????????????????????????????????????????????????
- ????????????????});???
?????????????????????????????????????????????????????????????????????????????????????????????????????
针对集合中只有一个元素的情况:?
Iterables.getOnlyElement();?
这个主要是用来替换Set.iterator.next()或 List.get(0), 而且在测试中使用非常方便, 如果出现0个或者2+则直接抛出异常?
比较的最大最小值:?
Comparators.max?
Comparators.min?
equals和hashcode的用法:?
Java代码?
?
- public?boolean?equals(Object?o)?{??
- ??if?(o?instanceof?Order)?{??
- ????Order?that?=?(Order)o;??
- ??
- ????return?Objects.equal(address,?that.address)??
- ????????&&?Objects.equal(targetArrivalDate,?that.targetArrivalDate)??
- ????????&&?Objects.equal(lineItems,?that.lineItems);??
- ??}?else?{??
- ????return?false;??
- ??}??
- }??
- ??
- public?int?hashCode()?{??
- ??return?Objects.hashCode(address,?targetArrivalDate,?lineItems);??
- }??
ImmutableList.copyOf的用法:?
以前这么用:?
Java代码?
?
- public?Directions(Address?from,?Address?to,?List<Step>?steps)?{??
- ??this.from?=?from;??
- ??this.to?=?to;??
- ??this.steps?=?Collections.unmodifiableList(new?ArrayList<Step>(steps));??
- }??
现在这么用:?
Java代码?
?
- public?Directions(Address?from,?Address?to,?List<Step>?steps)?{??
- ??this.from?=?from;??
- ??this.to?=?to;??
- ??this.steps?=?ImmutableList.of(steps);??
- }??
Iterables.concat()的用法:?
以前这么用:?
Java代码?
?
- public?boolean?orderContains(Product?product)?{??
- ??List<LineItem>?allLineItems?=?new?ArrayList<LineItem>();??
- ??allLineItems.addAll(getPurchasedItems());??
- ??allLineItems.addAll(getFreeItems());??
- ??
- ??for?(LineItem?lineItem?:?allLineItems)?{??
- ????if?(lineItem.getProduct()?==?product)?{??
- ??????return?true;??
- ????}??
- ??}??
- ??
- ??return?false;??
- }??
现在这么用:?
Java代码?
?
- public?boolean?orderContains(Product?product)?{??
- ??for?(LineItem?lineItem?:?Iterables.concat(getPurchasedItems(),?getFreeItems()))?{??
- ????if?(lineItem.getProduct()?==?product)?{??
- ??????return?true;??
- ????}??
- ??}??
- ??
- ??return?false;??
- }??
Constraints.constrainedList: 给List操作注入约束逻辑, 比如添加不合法元素直接报错.?
以前这么写:?
Java代码?
?
- private?final?List<LineItem>?purchases?=?new?ArrayList<LineItem>();??
- ??
- ?
- ?
- ?
- ??
- public?List<LineItem>?getPurchases()?{??
- ??return?Collections.unmodifiableList(purchases);??
- }??
- ??
- public?void?addPurchase(LineItem?purchase)?{??
- ??Preconditions.checkState(catalog.isOffered(getAddress(),?purchase.getProduct()));??
- ??Preconditions.checkState(purchase.getCharge().getUnits()?>?0);??
- ??purchases.add(purchase);??
- }??
- 这么写:??
- private?final?List<LineItem>?purchases?=?Constraints.constrainedList(??
- ????new?ArrayList<LineItem>(),??
- ????new?Constraint<LineItem>()?{??
- ??????public?void?checkElement(LineItem?element)?{??
- ????????Preconditions.checkState(catalog.isOffered(getAddress(),?element.getProduct()));??
- ????????Preconditions.checkState(element.getCharge().getUnits()?>?0);??
- ??????}??
- ????});??
- ??
- ?
- ?
- ??
- public?List<LineItem>?getPurchases()?{??
- ??return?purchases;??
- }??
不允许插入空值的Set(Constraints的用法):?
Java代码?
?
- Set<String>?set?=?Sets.newHashSet();??
- Set<String>?constrainedSet?=?Constraints.constrainedSet(set,?Constraints.notNull());??
- constrainedSet.add("A");??
- constrainedSet.add(null);???
Multimap的用法(允许多值的map):?
以前这么写:?
Java代码?
?
- Map<Salesperson,?List<Sale>>?map?=?new?Hashmap<SalesPerson,?List<Sale>>();??
- ??
- public?void?makeSale(Salesperson?salesPerson,?Sale?sale)?{??
- ??List<Sale>?sales?=?map.get(salesPerson);??
- ??if?(sales?==?null)?{??
- ????sales?=?new?ArrayList<Sale>();??
- ????map.put(salesPerson,?sales);??
- ??}??
- ??sales.add(sale);??
- }??
现在这么写:?
Java代码?
?
- Multimap<Salesperson,?Sale>?multimap???
- ????=?new?ArrayListMultimap<Salesperson,Sale>();??
- ??
- public?void?makeSale(Salesperson?salesPerson,?Sale?sale)?{??
- ??multimap.put(salesperson,?sale);??
- }??
以前这么写:?
Java代码?
?
- public?Sale?getBiggestSale()?{??
- ??Sale?biggestSale?=?null;??
- ??for?(List<Sale>?sales?:?map.values())?{??
- ????Sale?biggestSaleForSalesman??
- ????????=?Collections.max(sales,?SALE_COST_COMPARATOR);??
- ????if?(biggestSale?==?null??
- ????????||?biggestSaleForSalesman.getCharge()?>?biggestSale().getCharge())?{??
- ??????biggestSale?=?biggestSaleForSalesman;??
- ????}??
- ??}??
- ??return?biggestSale;??
- }??
现在这么写(需要将map转换成multimap):?
Java代码?
?
- public?Sale?getBiggestSale()?{??
- ??return?Collections.max(multimap.values(),?SALE_COST_COMPARATOR);??
- }??
Joiner的用法:?
以前这样写:?
Java代码?
?
- public?class?ShoppingList?{??
- ??private?List<Item>?items?=?...;??
- ??
- ??...??
- ??
- ??public?String?toString()?{??
- ????StringBuilder?stringBuilder?=?new?StringBuilder();??
- ????for?(Iterator<Item>?s?=?items.iterator();?s.hasNext();?)?{??
- ??????stringBuilder.append(s.next());??
- ??????if?(s.hasNext())?{??
- ????????stringBuilder.append("?and?");??
- ??????}??
- ????}??
- ????return?stringBuilder.toString();??
- ??}??
- }??
现在这样写:?
Java代码?
?
- public?class?ShoppingList?{??
- ?private?List<Item>?items?=?...;??
- ??
- ?...??
- ??
- ?public?String?toString()?{??
- ???return?Join.join("?and?",?items);??
- ?}??
- }??
Comparators.fromFunction的用法:?
以前这样写:?
Java代码?
?
- public?Comparator<Product>?createRetailPriceComparator(??
- ????final?CurrencyConverter?currencyConverter)?{??
- ??return?new?Comparator<Product>()?{??
- ????public?int?compare(Product?a,?Product?b)?{??
- ??????return?getRetailPriceInUsd(a).compareTo(getRetailPriceInUsd(b));??
- ????}??
- ????public?Money?getRetailPriceInUsd(Product?product)?{??
- ??????Money?retailPrice?=?product.getRetailPrice();??
- ??????return?retailPrice.getCurrency()?==?CurrencyCode.USD??
- ????????????retailPrice??
- ??????????:?currencyConverter.convert(retailPrice,?CurrencyCode.USD);??
- ????}??
- ??};??
- }??
现在这样写(感觉也没省多少):?
Java代码?
?
- public?Comparator<Product>?createRetailPriceComparator(??
- ????final?CurrencyConverter?currencyConverter)?{??
- ??return?Comparators.fromFunction(new?Function<Product,Money>()?{??
- ??????
- ????public?Money?apply(Product?product)?{??
- ??????Money?retailPrice?=?product.getRetailPrice();??
- ??????return?retailPrice.getCurrency()?==?CurrencyCode.USD??
- ????????????retailPrice??
- ??????????:?currencyConverter.convert(retailPrice,?CurrencyCode.USD);??
- ????}??
- ??});??
- }??
BiMap(双向map)的用法:?
以前的用法:?
Java代码?
?
- private?static?final?Map<Integer,?String>?NUMBER_TO_NAME;??
- private?static?final?Map<String,?Integer>?NAME_TO_NUMBER;??
- ??
- static?{??
- ??NUMBER_TO_NAME?=?Maps.newHashMap();??
- ??NUMBER_TO_NAME.put(1,?"Hydrogen");??
- ??NUMBER_TO_NAME.put(2,?"Helium");??
- ??NUMBER_TO_NAME.put(3,?"Lithium");??
- ????
- ????
- ??NAME_TO_NUMBER?=?Maps.newHashMap();??
- ??for?(Integer?number?:?NUMBER_TO_NAME.keySet())?{??
- ????NAME_TO_NUMBER.put(NUMBER_TO_NAME.get(number),?number);??
- ??}??
- }??
- ??
- public?static?int?getElementNumber(String?elementName)?{??
- ??return?NUMBER_TO_NAME.get(elementName);??
- }??
- ??
- public?static?string?getElementName(int?elementNumber)?{??
- ??return?NAME_TO_NUMBER.get(elementNumber);??
- }??
现在的用法:?
Java代码?
?
- private?static?final?BiMap<Integer,String>?NUMBER_TO_NAME_BIMAP;??
- ??
- static?{??
- ??NUMBER_TO_NAME_BIMAP?=?Maps.newHashBiMap();??
- ??NUMBER_TO_NAME_BIMAP.put(1,?"Hydrogen");??
- ??NUMBER_TO_NAME_BIMAP.put(2,?"Helium");??
- ??NUMBER_TO_NAME_BIMAP.put(3,?"Lithium");??
- }??
- ??
- public?static?int?getElementNumber(String?elementName)?{??
- ??return?NUMBER_TO_NAME_BIMAP.inverse().get(elementName);??
- }??
- ??
- public?static?string?getElementName(int?elementNumber)?{??
- ??return?NUMBER_TO_NAME_BIMAP.get(elementNumber);??
- }??
换一种写法:?
Java代码?
?
- private?static?final?BiMap<Integer,String>?NUMBER_TO_NAME_BIMAP??
- ??=?new?ImmutableBiMapBuilder<Integer,String>()??
- ??????.put(1,?"Hydrogen")??
- ??????.put(2,?"Helium")??
- ??????.put(3,?"Lithium")??
- ??????.getBiMap();??
关于Strings的一些用法(http://blog.ralscha.ch/?p=888):?
Java代码?
?
- assertEquals("test",?Strings.emptyToNull("test"));??
- assertEquals("?",?Strings.emptyToNull("?"));??
- assertNull(Strings.emptyToNull(""));??
- assertNull(Strings.emptyToNull(null));??
- ???
- assertFalse(Strings.isNullOrEmpty("test"));??
- assertFalse(Strings.isNullOrEmpty("?"));??
- assertTrue(Strings.isNullOrEmpty(""));??
- assertTrue(Strings.isNullOrEmpty(null));??
- ???
- assertEquals("test",?Strings.nullToEmpty("test"));??
- assertEquals("?",?Strings.nullToEmpty("?"));??
- assertEquals("",?Strings.nullToEmpty(""));??
- assertEquals("",?Strings.nullToEmpty(null));??
- ???
- assertEquals("Ralph_____",?Strings.padEnd("Ralph",?10,?'_'));??
- assertEquals("Bob_______",?Strings.padEnd("Bob",?10,?'_'));??
- ???
- assertEquals("_____Ralph",?Strings.padStart("Ralph",?10,?'_'));??
- assertEquals("_______Bob",?Strings.padStart("Bob",?10,?'_'));??
- ??
- assertEquals("xyxyxyxyxy",?Strings.repeat("xy",?5));??
Throwables的用法(将检查异常转换成未检查异常):?
Java代码?
?
- package?com.ociweb.jnb.apr2010;??
- ??
- import?com.google.common.base.Throwables;??
- ??
- import?java.io.InputStream;??
- import?java.net.URL;??
- ??
- public?class?ExerciseThrowables?{??
- ????public?static?void?main(String[]?args)?{??
- ????????try?{??
- ????????????URL?url?=?new?URL("http://ociweb.com");??
- ????????????final?InputStream?in?=?url.openStream();??
- ??????????????
- ????????????in.close();??
- ????????}?catch?(Throwable?t)?{??
- ????????????throw?Throwables.propagate(t);??
- ????????}??
- ????}??
- }??
Multimap用法整理(http://jnb.ociweb.com/jnb/jnbApr2008.html):?
用来统计多值出现的频率:?
Java代码?
?
- Multimap<Integer,?String>?siblings?=?Multimaps.newHashMultimap();??
- siblings.put(0,?"Kenneth");??
- siblings.put(1,?"Joe");??
- siblings.put(2,?"John");??
- siblings.put(3,?"Jerry");??
- siblings.put(3,?"Jay");??
- siblings.put(5,?"Janet");??
- ??
- for?(int?i?=?0;?i?<?6;?i++)?{??
- ????int?freq?=?siblings.get(i).size();??
- ????System.out.printf("%d?siblings?frequency?%d\n",?i,?freq);??
- }??
输出结果:?
引用
??????? 0 siblings frequency 1?
??????? 1 siblings frequency 1?
??????? 2 siblings frequency 1?
??????? 3 siblings frequency 2?
??????? 4 siblings frequency 0?
??????? 5 siblings frequency 1
Functions(闭包功能)?
Java代码?
?
- Function<String,?Integer>?strlen?=?new?Function<String,?Integer>()?{??
- ????public?Integer?apply(String?from)?{??
- ????????Preconditions.checkNotNull(from);??
- ????????return?from.length();??
- ????}??
- };??
- List<String>?from?=?Lists.newArrayList("abc",?"defg",?"hijkl");??
- List<Integer>?to?=?Lists.transform(from,?strlen);??
- for?(int?i?=?0;?i?<?from.size();?i++)?{??
- ????System.out.printf("%s?has?length?%d\n",?from.get(i),?to.get(i));??
- }??
不过这种转换是在访问元素的时候才进行, 下面的例子可以说明:?
Java代码?
?
- Function<String,?Boolean>?isPalindrome?=?new?Function<String,?Boolean>()?{??
- ????public?Boolean?apply(String?from)?{??
- ????????Preconditions.checkNotNull(from);??
- ????????return?new?StringBuilder(from).reverse().toString().equals(from);??
- ????}??
- };??
- List<String>?from?=?Lists.newArrayList("rotor",?"radar",?"hannah",?"level",?"botox");??
- List<Boolean>?to?=?Lists.transform(from,?isPalindrome);??
- for?(int?i?=?0;?i?<?from.size();?i++)?{??
- ????System.out.printf("%s?is%sa?palindrome\n",?from.get(i),?to.get(i)???"?"?:?"?NOT?");??
- }???
- ??
- System.out.printf("\nnow?replace?hannah?with?megan...\n\n");??
- from.set(2,?"megan");??
- for?(int?i?=?0;?i?<?from.size();?i++)?{??
- ????System.out.printf("%s?is%sa?palindrome\n",?from.get(i),?to.get(i)???"?"?:?"?NOT?");??
- } ?