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

Google Guava学习笔记

2014-09-15 17:31 701 查看
Java Collection Framework的增强工具类Google Guava Collection
使用这个工具包的主要原因是为了当使用collection等类处理复杂逻辑的时候,可以使用Guava collection帮助完成这些工作。使得代码等短,代码质量更高,同时更容易阅读和修改。

功能举例:
Multiset: 能够把重复的元素放入一个集合,并且可以统计元素数量
Multimap:能够实现同一个key对应多个元素,不用自己繁琐地实现
BiMap:key不重复,value也不重复
Ordering: 作为比较器进行排序,简化代码

如果你对上述功能有兴趣,那请你继续阅读。

函数式编程:Function和Predicate

Function类:通过Function类将指定的集合类转变为我们想要的集合类
Predicate类:通过Predicate类将制定的集合类进行过滤,从而剔除集合中不想要的元素

首先我们构建一个Company类
package rich.model;

import java.util.Arrays;
import java.util.List;

import com.google.common.collect.Lists;

public class Company {

private List<Company> companies;
private String name;
private String location;

public static Company newCompany(String name, String loc) {
Company company = new Company();
company.setName(name);
company.setLocation(loc);
return company;
}

public void init() {
companies = Lists.newArrayList();
companies.addAll(Arrays.asList(Company.newCompany("quest", "zhuhai"),Company.newCompany("dell", "toronto")));
}
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getLocation() {
return location;
}

public void setLocation(String location) {
this.location = location;
}

public List<Company> getCompanies() {
return companies;
}

public void setCompanies(List<Company> companies) {
this.companies = companies;
}
}
其次我们构建一个FunctionTest,用于测试Function类的功能:
package rich.base;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import rich.model.Company;

import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.base.Functions;

public class FunctionTest {

public static void main(String[] args) {
//接口Function<F,T> {T apply(F input) }
//把一种形式的Collection<F>转换成另一种Collection<T>
Function<Company, String> function1 = new Function<Company, String>() {
@Override
public String apply(Company company) {
return company.getLocation();
}
};
//进行转换
Company company = new Company();
company.init();
List<String> companyLocationList = Lists.transform(company.getCompanies(), function1);
//Collection<String> collectionCompanyList = Collections2.transform(company.getCompanies(), function1);
for(int i = 0; i < companyLocationList.size(); i++) {
System.out.println(companyLocationList.get(i));
}

//除此之外,还可以进行组合运算
//新function
Function<String, String> function2 = new Function<String, String>() {
@Override
public String apply(String s) {
return s.toUpperCase();
}
};
//重新定义一个function3,将function1和function2组合在一起
//使用Functions的compose方法
Function<Company, String> function3 = Functions.compose(function2, function1);
//转换集合
Collection<String> upperLocationList = Collections2.transform(company.getCompanies(), function3);
System.out.println(upperLocationList.contains("ZHUHAI"));

//还有map方法
Map<Company, String> map = Maps.newHashMap();
map.put(company.getCompanies().get(0), "bigCompany");
//function4
Function<Company, String> function4 = Functions.forMap(map,"UNKNOWN");
//进行映射,即若有zhuhai这个对象,则返回bigCompany这个值
//如果对象没有对应的map value,则返回default value "UNKNOWN"
Collection<String> types = Collections2.transform(company.getCompanies(), function4);
Iterator typeIterator = types.iterator();
while(typeIterator.hasNext()){
System.out.println(typeIterator.next());
}
}
}

上述例子主要实现了Function的主功能,把一个集合类companies从Company类转换为String类型,利用了guava包中的集合工具类都有的transform方法,通过传入原始集合和function实例,生成新的集合,只要实现了function接口类中的apply方法就可以了,其中泛型中第一个参数是原始集合的类型,第二个参数是目的集合的类型。还可以使用对应的工具类Functions的compose方法进行组合的Function运算,应对复杂的算法逻辑。同时,还有对应map方法,通过Functions的forMap方法,将map中value值通过function转换为新的collection。
Predicate类,与Function类类似,这里也提供一个PredicateTest来进行测试。
package rich.base;

import java.util.Collection;
import java.util.Iterator;

import rich.model.Company;

import com.google.common.base.Functions;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Collections2;

public class PredicateTest {

public static void main(String[] args) {
//Predicate主要用于对Collection的值进行过滤
Predicate<Company> predicate1 = new Predicate<Company>(){
@Override
public boolean apply(Company company) {
if(company.getName() == "quest") {
return true;
} else
return false;
}
};
Company company = new Company();
company.init();
//进行过滤
Collection<Company> companyList1 = Collections2.filter(company.getCompanies(), predicate1);
Iterator<Company> c1 = companyList1.iterator();
while(c1.hasNext()) {
System.out.println(c1.next().getLocation());
}

//有一个Predicates类用于对Predicate接口进行操作,用法与Functions类似
Predicate<Company> predicate2 = new Predicate<Company>(){
@Override
public boolean apply(Company company) {
if(company.getLocation() == "zhuhai") {
return true;
} else
return false;
}
};

//and 和 or
Predicate<Company> predicateOr = Predicates.or(predicate1, predicate2);
//Predicate<Company> predicateOr = Predicates.and(predicate1, predicate2);
Collection<Company> companyList2 = Collections2.filter(company.getCompanies(), predicateOr);
Iterator<Company> c2 = companyList2.iterator();
while(c2.hasNext()) {
System.out.println(c2.next().getLocation());
}

//构造简易的Predicate过滤集
Collection<Company> companyList3 = Collections2.filter(company.getCompanies(), Predicates.notNull());
//Collection<Company> companyList4 = Collections2.filter(company.getCompanies(), Predicates.alwaysTrue());
}
}

与Function接口类似,Predicate接口类也是需要实现其apply的方法,并使用Guava包中集合工具类的filter方法对集合元素进
4000
行过滤。当然,也提供对应的工具类Predicates的and,or,not等方法进行复杂逻辑的过滤,并提供诸如Predicates.notNull或Predicates.alwaysTrue等简单的predicate实例方法。

下面贴出我看的两个包Base包和collect包和其测试方法。仅供参考,如有问题,请留言,我会尽快回复。

Base包:

ObjectsTest

package rich.base;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import com.google.common.base.Joiner;
import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
/*
* base 包大多是用于判断值是否为空和判断相等的方法集合包
*/
public class ObjectsTest {

public static void main(String[] args) {

//Objects
//判断两个对象是否相等。
System.out.println(Objects.equal("1", "2"));
//Objects的方法都移到了MoreObject上
//一般是用来判断第一个参数值是否为空,若为空,则返回第二个参数的值。
System.out.println(MoreObjects.firstNonNull(null, 2));
//StringHelper是moreOjbects的静态内部类,使用MoreObjects.toStringHelper获得
MoreObjects.ToStringHelper stringHelper = MoreObjects.toStringHelper("MyObject").add("a", 1);
System.out.println(stringHelper);

//Strings
//判断string为null或者“”
System.out.println(Strings.isNullOrEmpty(""));
//将空的string转变为null对象,相对应的有nullToEmpty
System.out.println(Strings.emptyToNull(""));
//重复String
System.out.println(Strings.repeat("abc", 5));

//Joiner
//String有split方法,但String数组没有join方法
String[] joinStrArray = new String[]{"abc","bdc","dfg" };
//没有循环的join方法, 还可以用skipNulls方法剔除null objects
Joiner joiner = Joiner.on(",");
String joinerString = joiner.join(joinStrArray);
//for(int i = 0; i < joinStrArray.size(); i++) { String joinerStr += (joinStrArray[i] + ",") } 更优雅一些,right?
System.out.println(joinerString);
//使用MapJoin
Map<String, String> joinMapArray = new HashMap<String, String>();
joinMapArray.put("lu", "rich");
joinMapArray.put("hong", "alex");
joinMapArray.put("wang", "sinba");
Joiner.MapJoiner mapJoiner = joiner.withKeyValueSeparator("-");
System.out.println(mapJoiner.join(joinMapArray));
//还可以加到StringBuilder中,不展开
//joinerString.split(",");是数组
//Splitter
Splitter splitter = Splitter.on(",").trimResults();
//拿回上面使用的joinerString
Iterable<String> splitterStrArray = splitter.split(joinerString);
Iterator<String> iterator = splitterStrArray.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
//感觉原方法更好一些。
//	 String[] test = joinerString.split(",");
//	 for(int i = 0; i < test.length; i++) {
//	 System.out.println(test[i]);
//	 }
//Splitter也有mapSplitter方法
Splitter.MapSplitter mapSplitter = splitter.withKeyValueSeparator("-");
Map<String, String> mapSplitterArray = mapSplitter.split(mapJoiner.join(joinMapArray));
Collection<String> collectMap = mapSplitterArray.values();
Iterator<String> c = collectMap.iterator();
while(c.hasNext()) {
System.out.println(c.next());
}
}
}

PreconditionsTest
package rich.base;

import rich.model.Company;

import com.google.common.base.Preconditions;

public class PreconditionsTest {

public static void main(String[] args) {

Company company = new Company();
company.init();
//Preconditions用来检查参数值是否符合预期
Preconditions.checkNotNull(company.getCompanies().get(0), "Check whether has a null object");
//如果为null值,则会抛exception,并提示errorMessage
Preconditions.checkNotNull(null, "this is a null object");
Preconditions.checkArgument(1 < 0, "this is a wrong answer.");
//数组下标少于size
Preconditions.checkElementIndex(3, company.getCompanies().size());
}
}

Collection包:

ListsTest

package rich.collect;

import java.util.ArrayList;
import java.util.List;

import rich.model.Company;

import com.google.common.base.Function;
import com.google.common.collect.Lists;

public class ListsTest {

public static void main(String[] args) {
//分配一个arrayList 方法与
//List<Company> companies = new ArrayList<Company>();
//一样
List<Company> companies = Lists.newArrayList();
//还可以指定初始大小
//List<Company> companies = Lists.newArrayListWithCapacity(10);
//List<Company> companies = Lists.newArrayListWithExpectedSize(20);
companies.add(Company.newCompany("oracle", "shenzhen"));
companies.add(Company.newCompany("tecent", "shenzhen"));

//创建LinkedList
List<Company> companies2 = Lists.newLinkedList();

//reverse list
List<Company> reverseCompanyList = Lists.reverse(companies);
//将list切分成大小为1的list数组返回
List<List<Company>> partitionCompanyList = Lists.partition(companies, 1);
//复制一个list
List<Company> copyCompanyList = Lists.newCopyOnWriteArrayList(companies);
System.out.println();
//Arrays.asList()
String[] testList = {"acb","bdc"};
//可以继续加单个object到list中,并对数组进行list转换
List<String> transformList = Lists.asList("dd", testList);
System.out.println(transformList.contains("dd"));
//transform方法配合function类使用
Function<Company, String> functionList = new Function<Company, String>() {
@Override
public String apply(Company company) {
return company.getName();
}
};
Lists.transform(companies, functionList);
//没有filter方法
}
}

SetsTest

package rich.collect;

import java.util.Set;

import rich.model.Company;

import com.google.common.base.Predicate;
import com.google.common.collect.Sets;

public class SetsTest {

public static void main(String[] args) {
Company company = new Company();
company.init();
//Set 方法与list类似,只是对象集元素不重复
Set<Company> companySet = Sets.newHashSet();
companySet.addAll(company.getCompanies());
//newTreeSet,newLinkedHashSet()
Predicate<Company> predicate = new Predicate<Company>() {
@Override
public boolean apply(Company company) {
if(company.getName().equals("dell")) return false;
return true;
}
};
Set<Company> filterSet = Sets.filter(companySet, predicate);
System.out.println(filterSet.contains(company.getCompanies().get(1)));
}
}

MapsTest

package rich.collect;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import rich.model.Company;

import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Maps;

public class MapsTest {

public static void main(String[] args) {
Company company = new Company();
company.init();
List<Company> companies = company.getCompanies();
//Maps 创建一个map
Map<Company, String> companyMap = Maps.newHashMap();
//Map<Company, String> companyMapUtil = new HashMap<Company, String>();
companyMap.put(companies.get(0), "subsidiary");
companyMap.put(companies.get(1), "parentCompany");
//与Lists类似,可以创建expectedSize的
Map<Company, String> companyMap1 = Maps.newHashMapWithExpectedSize(10);
//也有newLinkHashMap,newTreeMap和newEnumMap
//同样的,也可以使用Function和Predicate类进行转换和过滤
//Function
Function<String, String> function = new Function<String, String>() {
@Override
public String apply(String relation) {
return relation + " is wrapped";
}
};
Map<Company, String> transformMap = Maps.transformValues(companyMap, function);
System.out.println(transformMap.containsValue("subsidiary is wrapped"));

//Predicate
Predicate<String> valuePredicate= new Predicate<String>() {
@Override
public boolean apply(String relation) {
if(relation.equals("UNKNOWN")) return false;
return true;
}

};
companyMap.put(Company.newCompany("oracle", "shenzhen"), "UNKNOWN");
Map<Company, String> filterValueMap = Maps.filterValues(companyMap, valuePredicate);
System.out.println(filterValueMap.containsValue("UNKNOWN"));
//除了value filter,还可以key filter,方法类似,不展开
}
}

IteralbesTest

package rich.collect;

import java.util.List;

import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;

import rich.model.Company;

public class IterablesTest {

public static void main(String[] args) {
//Iterables扩展iterable集合类方法
Company company = new Company();
company.init();
//concat方法,串联list,set,vector等集合类
List<Company> newCompanyList = Lists.newArrayList();
newCompanyList.add(Company.newCompany("oracle", "shenzhen"));
newCompanyList.add(Company.newCompany("tecent", "shenzhen"));
Iterable iterablesList = Iterables.concat(newCompanyList, company.getCompanies());

//集合类方法,一般都会有function和Predicate方法。
//就是transform和filter方法,不展开
//但说一说find方法,find方法是找到第一个符合条件的value返回
Predicate<Company> predicate = new Predicate<Company>() {
@Override
public boolean apply(Company company) {
return company.getName() == "quest";
}
};

Company matchCompany = Iterables.find(iterablesList, predicate);
//因为如果找不到值的话,会报异常,所以一般会使用加defaultValue的find方法
Company matchCompany1 = Iterables.find(iterablesList, predicate, Company.newCompany("emc", "shanghai"));
if(matchCompany != null) {
System.out.println(matchCompany.getName());
}
//iterable是没有size的方法,所以可以使用Iterables.size()方法
System.out.println(Iterables.size(iterablesList));
//还有就是getFirst和getLast方法,toArray方法,isEmpty方法等等,不展开
}
}

OrdingTest

package rich.collect;

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;

import rich.model.Company;

import com.google.common.collect.ComparisonChain;
import com.google.common.collect.Ordering;

public class OrderingTest {

public static void main(String[] args) {
//Ordering类,实现Comparator接口
Ordering<Company> ordering = new Ordering<Company>() {
@Override
public int compare(Company company1, Company company2) {
return company1.getName().length() - company2.getName().length();
}
};

//使用compound方法,组合解决Comparator接口
Comparator<Company> comparator1 = new Comparator<Company>() {
@Override
public int compare(Company o1, Company o2) {
return o1.getLocation().length() - o1.getLocation().length();
}
};

Comparator<Company> comparator2 = new Comparator<Company>() {
@Override
public int compare(Company o1, Company o2) {
return o1.getName().length() - o1.getName().length();
}
};

Ordering<Company> ordering2 = Ordering.compound(Arrays.asList(comparator1, comparator2));
//进行排序
Company company = new Company();
company.init();
Collections.sort(company.getCompanies(), ordering2);

}
}

SpecificalMapTest有趣的方法都在这里了,请详阅

SpecificalMapTest

package rich.collect;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.common.collect.HashBiMap;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multiset;

public class SpecificalMapTest {

public static void main(String[] args) {
//Multiset 把重复元素的放入集合
//可以用于统计重复元素的数量
//例如有一个list里面有各种字符串,你要统计每个字符串在list里面出现的次数,偏向于一个bag的概念
List<String> wordList = getWordList();
//	 Map<String, Integer> map = new HashMap<String, Integer>();
//	 for(String word : wordList){
//	 Integer count = map.get(word);
//	 map.put(word, (count == null) ? 1 : count + 1);
//	 }
//	 Integer count = map.get("a");
//Multiset用法
Multiset<String> multiSet = HashMultiset.create();
multiSet.addAll(wordList);
int count = multiSet.count("a");
System.out.println(count + "--" + multiSet.size());
multiSet.setCount("a", 5);
System.out.println(multiSet.count("a") + "--" + multiSet.size());

//Multimap 在Map中value里面放多个元素
//Map 的值像{k1=v1,k2=v2,...} Multimap像{k1=[v1,v2,v3],k2=[v4,v5],...}
//当然我们也可以这样构建一个对象,这也是可以的,但显得有些麻烦
HashMap<String, HashSet<String>> map = new HashMap<String, HashSet<String>>();
//Multimap用法,与上面等价
Multimap<String, String> hashMultimap = HashMultimap.create(); //HashSet不能存储相同value元素,继承SetMultimap
hashMultimap.put("dell", "zhuhai");
hashMultimap.put("dell", "shanghai");
hashMultimap.put("dell", "shanghai");
Collection<String> mapCollection = hashMultimap.get("dell");
Iterator c = mapCollection.iterator();
while(c.hasNext()) {
System.out.println(c.next());
}
//除了HashMultimap,还有ArrayListMultimap,LinkedHashMultimap,TreeMultimap,ImmutableMultimap 不展开

//BiMap value和key都不能重复 可以根据value推断key值
//也可以key和value互换
HashBiMap<String, String> biMap = HashBiMap.create();
biMap.inverse();
//RangeMap

}

public static List<String> getWordList() {
List<String> wordList = new ArrayList<String>();
wordList.add("a");
wordList.add("ab");
wordList.add("ab");
wordList.add("a");
wordList.add("a");
wordList.add("c");
return wordList;
}
}

Primitive包

PrimitivesTest

package rich.primitive;

import java.util.Collections;
import java.util.List;

import com.google.common.collect.Lists;
import com.google.common.primitives.Doubles;

public class PrimitivesTest {

public static void main(String[] args) {
//Double,float,int,boolean等等
//Double.valueOf("12.2bb");
Double.parseDouble("");
//用这种方法的主要原因是因为错误的时候不会抛出exception,如果错误的时候返回的是null值
Doubles.tryParse("12.0bb");

double[] abc = {12.0,52.1};
Doubles.max(abc);
Doubles.min(abc);

//当然你也可以使用Collection的max和min方法。不用重写comparator
List<Integer> testCollection = Lists.newArrayList();
testCollection.add(2);
testCollection.add(1);
testCollection.add(3);
System.out.println(Collections.max(testCollection));

//数组是否有12.0这个值
Doubles.contains(abc, 12.0);
//数组和集合的转换
//asList和toArray方法
//indexOf和lastIndexOf方法
}
}


guava中文 api(不全)
http://ifeve.com/google-guava/

guava home page: https://code.
ac05
google.com/p/guava-libraries/
the latest version: guava-18.0.jar

about guava api
http://docs.guava-libraries.googlecode.com/git/javadoc/index.html

Java Collection Framework

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