您的位置:首页 > 编程语言 > Go语言

Google Guava 库用法整理

2014-04-04 11:03 295 查看
GoogleJavaBlogguava 

参考: 
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>();  

  

/** 

 * Don't modify this! Instead, call {@link #addPurchase(LineItem)} to add 

 * new purchases to this order. 

 */  

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);  

      }  

    });  

  

/** 

 * Returns the modifiable list of purchases in this order. 

 */  

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); // NullPointerException here  

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>() {  

    /** returns the retail price in USD */  

    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");  

    

  /* reverse the map programatically so the actual mapping is not repeated */  

  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();  

            // read from the input stream  

            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 ");  

}   

// changes in the "from" list are reflected in the "to" list  

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 ");  

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: