Google Guava学习笔记

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方法对集合元素进行过滤。当然,也提供对应的工具类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(不全)

the latest version: guava-18.0.jar

about guava api


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值