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

Google Guava 库用法整理

2015-11-12 00:00 465 查看

Google Guava 库用法整理

博客分类:

Guava

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

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