1.对字符串的操做:javascript
package com.wenniuwuren.guava; import java.io.UnsupportedEncodingException; import java.util.Date; import java.util.HashMap; import com.google.common.base.CharMatcher; import com.google.common.base.Charsets; import com.google.common.base.Objects; import com.google.common.base.Strings; import com.google.common.collect.ComparisonChain; import sun.org.mozilla.javascript.internal.ast.TryStatement; /** * * @ClassName: WorkingWithStrings * @Description: 对字符串的操做 * @author wenniuwuren * @date 2015-5-20 上午11:33:59 * */ public class WorkingWithStrings { public static void main(String[] args) throws UnsupportedEncodingException { // 问题: 1."UTF-8"必须在Java平台中被支持 2.人工敲入会有误差 // byte[] bytes = "foo".getBytes("UTF-8"); // 解决: Charsets类提供了对Java平台支持字符集 byte[] bytes = "foo".getBytes(Charsets.UTF_8); // 问题: 使用StringBuilder类链接字符串太繁琐, 代码其实都是重复的 // 解决: Strings类封装了链接字符串的统一代码 System.out.println("padEnd"); String stringsTest = Strings.padEnd("foo", 6, 'o'); System.out.println(stringsTest); // 在String做为参数时,将null转换成""防止空指针问题 System.out.println("nullToEmpty"); String nullToEmptyTest1 = Strings.nullToEmpty("123"); String nullToEmptyTest2 = Strings.nullToEmpty(null); System.out.println(nullToEmptyTest1 + "--" + nullToEmptyTest2); // ""转null System.out.println("emptyToNull"); String emptyToNullTest1 = Strings.emptyToNull("123"); String emptyToNullTest2 = Strings.emptyToNull(""); System.out.println(emptyToNullTest1 + "--" + emptyToNullTest2); // 将字符串中的Tab和多个空格转为一个空格 String tabsAndSpaces = "String with spaces and tabs"; String expected = "String with spaces and tabs"; String scrubbed = CharMatcher.WHITESPACE.collapseFrom(tabsAndSpaces,' '); System.out.println(expected.equals(scrubbed)); // Object utilities 对象工具 // 1. toString()实现 System.out.println(Objects.toStringHelper(WorkingWithStrings.class).omitNullValues() .add("expected", expected).add("tabsAndSpaces", tabsAndSpaces)); // 2. 检查若是为null值 , 填充默认值 System.out.println(Objects.firstNonNull(null, "default value")); // 3. 生成hashcode System.out.println(Objects.hashCode(tabsAndSpaces, expected)); // 4. CompareTo实现 若是都是相同的返回0,有一个不一样返回-1 System.out.println(ComparisonChain.start().compare(tabsAndSpaces, expected).compare(expected, scrubbed).result()); } }
2.FluentIterable迭代器:java
Guava提供了能够在Iterator中进行处理的功能更丰富的迭代器, 其实就像是加了一个代理, 增长一些功能。编程
package com.wenniuwuren.collections; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import com.google.common.base.Function; import com.google.common.base.Joiner; import com.google.common.base.Predicate; import com.google.common.collect.FluentIterable; import com.google.common.collect.Lists; /** * * @author wenniuwuren * */ public class FluentIterableTest { @SuppressWarnings("unchecked") public static void main(String[] args) { Person person1 = new Person("lilei", 50); Person person2 = new Person("hanmeimei", 40); @SuppressWarnings("rawtypes") ArrayList personList = Lists.newArrayList(person1, person2); //返回一个按条件过滤后的结果集 Iterable<Person> personFilterByAge = FluentIterable.from(personList) .filter(new Predicate<Person>() { @Override public boolean apply(Person input) { return input.getAge() > 40; } }); Iterator<Person> i = personFilterByAge.iterator(); while(i.hasNext()) { System.out.println("年龄大于40的是:" + i.next().getName()); } System.out.println("-------------我是邪恶的分割线-------------"); // 返回处理过的结果集 List<String> transformedPersonList = FluentIterable.from(personList) .transform(new Function<Person, String>() { @Override public String apply(Person input) { return Joiner.on(':').join(input.getName(), input.getAge()); } }).toList(); Iterator transformedPersonListIterator = transformedPersonList.iterator(); while(transformedPersonListIterator.hasNext()) { System.out.println("拼接起来的结果是:" + transformedPersonListIterator.next()); } } } class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
3.Lists列表:并发
package com.wenniuwuren.collections; import java.util.Iterator; import java.util.List; import com.google.common.collect.Lists; public class ListsTest { public static void main(String[] args) { Person person1 = new Person("lilei", 50); Person person2 = new Person("hanmeimei", 40); Person person3 = new Person("kangkang", 20); Person person4 = new Person("mary", 20); List<Person> personList = Lists.newArrayList(person1, person2, person3, person4); // 拆分红[person1, person2, person3], [person4] 第二个参数为拆分长度 List<List<Person>> subList = Lists.partition(personList, 3); Iterator<List<Person>> i = subList.iterator(); while(i.hasNext()) { List<Person> listTemp = (List<Person>)i.next(); Iterator<Person> iTemp = listTemp.iterator(); while(iTemp.hasNext()) { System.out.println(iTemp.next().getName()); } } } }
Table矩阵:app
使用Guava对矩阵的实现, 作一些矩阵存贮等操做将大大提升效率, 而不是本身用JDK的Array去实现, 可能带来很多bug, 并且增长代码复杂度。less
package com.wenniuwuren.collections; import java.util.Map; import com.google.common.collect.HashBasedTable; /** * Table: 矩阵的实现 * @author wenniuwuren * */ public class TableTest { public static void main(String[] args) { HashBasedTable<Integer,Integer,String> table = HashBasedTable.create(); table.put(1, 1, "11"); table.put(1, 2, "12"); table.put(1, 3, "13"); table.put(2, 1, "21"); table.put(2, 2, "22"); table.put(2, 3, "23"); boolean contains11 = table.contains(1,1); boolean containColumn2 = table.containsColumn(2); boolean containsRow1 = table.containsRow(1); boolean containsValue11 = table.containsValue("11"); table.remove(1,3); table.get(3,4); Map<Integer,String> columnMap = table.column(1); Map<Integer,String> rowMap = table.row(2); System.out.println(table + ", contains11:" + contains11 + ", containColumn2:" + containColumn2 + ", containsRow1:" + containsRow1 + ", containsValue11:" + containsValue11 + ", columnMap" + columnMap +", rowMap" + rowMap); } }
4.Sets:异步
package com.wenniuwuren.collections; import java.util.Iterator; import java.util.Set; import com.google.common.collect.Sets; /** * 对Sets工具类的使用 * @author wenniuwuren * */ public class SetsTest { public static void main(String[] args) { /** * 返回在s1中存在, 但再也不s2中存在的 */ Set<String> s1 = Sets.newHashSet("1", "2", "3"); Set<String> s2 = Sets.newHashSet("2", "3", "4"); System.out.println(Sets.difference(s1, s2)); /** * 返回两个集合互斥集合 */ System.out.println(Sets.symmetricDifference(s1, s2)); /** * 返回两个集合的交集 */ System.out.println(Sets.intersection(s1, s2)); /** * 返回两个集合的并集 */ System.out.println(Sets.union(s1, s2)); } }
本文介绍了Guava集合类Maps、BiMap、ArrayListMultimap相关的使用, 好比将具备惟一主键的对象快速存入Map、 键值对反转等ide
Maps集合类扩展使用 :函数式编程
package com.wenniuwuren.guava; import java.util.List; import java.util.Map; import java.util.NavigableMap; import java.util.Set; import com.google.common.base.Function; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; /** * * @ClassName: MapsTest * @Description: Maps集合类扩展使用 * @author wenniuwuren * @date 2015-6-1 下午5:23:22 * */ public class MapsTest { @SuppressWarnings("unchecked") public static void main(String[] args) { Person p1 = new Person("001", "zhang_san"); Person p2 = new Person("002", "li_si"); List<Person> personList = Lists.newArrayList(); personList.add(p1); personList.add(p2); // 将主键看成Map的Key Map<String, Person> personMap = Maps.uniqueIndex(personList.iterator(), new Function<Person, String>() { @Override public String apply(Person input) { return input.getId(); } }); System.out.println("将主键看成Map的Key:" + personMap); // 能够说是Maps.uniqueIndex相反的做用 Set<Person> personSet = Sets.newHashSet(p1, p2); @SuppressWarnings("unused") Map<Person, String> personAsMap= Maps.asMap(personSet, new Function() { @Override public Object apply(Object input) { return ((Person)input).getId(); } }); System.out.println(personAsMap); // 转换Map中的value值 Map<String, String> transformValuesMap = Maps.transformValues(personMap, new Function<Person, String>() { @Override public String apply(Person input) { return input.getName(); } }); System.out.println("转换Map中的value值" + transformValuesMap); } } class Person { private String Id; private String name; public Person(String Id, String name) { this.Id = Id; this.name = name; } public String getId() { return Id; } public void setId(String id) { Id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
对ArrayListMultiMap的使用案例:函数
package com.wenniuwuren.guava; import java.util.List; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.HashMultimap; import com.google.common.collect.Lists; /** * * @ClassName: ArrayListMultiMapTest * @Description: 一key对应多value * @author wenniuwuren * @date 2015-6-1 下午6:17:00 * */ public class ArrayListMultiMapTest { public static void main(String[] args) { /** * ArrayListMultimap List容许重复, 因此大小为4 */ ArrayListMultimap<String,String> multiMap = ArrayListMultimap.create(); multiMap.put("Foo","1"); multiMap.put("Foo","2"); multiMap.put("Foo","3"); multiMap.put("Foo","3"); System.out.println("内容:" + multiMap + " , 大小:" + multiMap.size()); /** * HashMultimap Hash不容许重复值, 大小为3 */ HashMultimap<String,String> hashMultiMap = HashMultimap.create(); hashMultiMap.put("Bar","1"); hashMultiMap.put("Bar","2"); hashMultiMap.put("Bar","3"); hashMultiMap.put("Bar","3"); hashMultiMap.put("Bar","3"); System.out.println("内容:" + hashMultiMap + " , 大小:" + hashMultiMap.size()); } }
对BiMaps使用案例:
package com.wenniuwuren.collections; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; /** * 对BiMap工具类的使用: key和value都是惟一的 * @author wenniuwuren * */ public class BiMapTest { public static void main(String[] args) { BiMap<String,String> biMap = HashBiMap.create(); biMap.put("1","Tom"); biMap.put("2","Jerry"); // 放入重复值value 将会报错 // biMap.put("2","Tom"); // 相同Value覆盖前一个 //biMap.forcePut("2","Tom"); System.out.println(biMap); // key value反转 System.out.println(biMap.inverse()); } }
本文介绍了Guava中Range的使用, 使用Range和Guava的函数式编程能够用少许代码实现指定范围内容的过滤。
import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.Range; /** * Guava Range类使用 * Created by wenniuwuren on 2015/6/3. */ public class RangeTest { public static void main(String[] args) { Range<Integer> numberRange = Range.closed(1, 10); System.out.println("closed包含边界" + numberRange.contains(10) + " ," + numberRange.contains(1)); Range<Integer> numberOpenRange = Range.open(1, 10); System.out.println("open不包含边界" + numberOpenRange.contains(1) + ", " + numberOpenRange.contains(10)); Range<Integer> atLeast = Range.atLeast(10); System.out.println("大于等于边界的全部值" + atLeast); Range<Integer> lessThan = Range.lessThan(10); System.out.println("小于等于边界的全部值" + lessThan); /** * 过滤掉不符合内容Range范围的 */ Range<Integer> ageRange = Range.closed(35,50); Function<Person,Integer> ageFunction = new Function<Person, Integer>() { @Override public Integer apply(Person person) { return person.getAge(); } }; Person p1 = new Person("zhangsan", 50); Person p2 = new Person("lisi", 70); Predicate<Person> predicate = Predicates.compose(ageRange, ageFunction); System.out.println("是否包含zhangsan:" + predicate.apply(p1) + ", 是否包含lisi:" + predicate.apply(p2)); } } class Person { private String name; private Integer age; public Person(String name, Integer age) { this.name = name; this.age = age; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
输出结果:
import com.google.common.collect.Lists; import com.google.common.collect.Ordering; import com.google.common.primitives.Ints; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; public class CityByPopluation implements Comparator<City> { @Override public int compare(City city1, City city2) { return Ints.compare(city1.getPopulation(), city2.getPopulation()); } public static void main(String[] args) { CityByPopluation cityByPopluation = new CityByPopluation(); CityByRainfall cityByRainfall = new CityByRainfall(); // 根据第二个参数排序 City city1 = new City("Beijing", 100000, 55.0); City city2 = new City("Shanghai", 100000, 45.0); City city3 = new City("ShenZhen", 100000, 33.8); List<City> cities = Lists.newArrayList(city1, city2, city3); /** * 单参数排序 */ // 排序反转 Ordering<City> firstOrdering = Ordering.from(cityByRainfall).reverse(); Collections.sort(cities, firstOrdering); Iterator<City> cityByRainfallIterator = cities.iterator(); while (cityByRainfallIterator.hasNext()) { System.out.println(cityByRainfallIterator.next().getCityName()); } System.out.println("I was evil dividing line"); /** * 多参数排序 */ Ordering<City> secondaryOrdering = Ordering. from(cityByPopluation).compound(cityByRainfall); Collections.sort(cities, secondaryOrdering); Iterator<City> cityIterator = cities.iterator(); while (cityIterator.hasNext()) { System.out.println(cityIterator.next().getCityName()); } /** * 取得最小最大值 */ Ordering<City> ordering = Ordering.from(cityByRainfall); // 降雨量最高的2个城市 List<City> topTwo = ordering.greatestOf(cities, 2); Iterator<City> topTwoIterator = topTwo.iterator(); while (topTwoIterator.hasNext()) { System.out.println("降雨量最高城市" + topTwoIterator.next().getCityName()); } // 降雨量最低的一个城市 List<City> bottomOne = ordering.leastOf(cities, 1); Iterator<City> bottomOneIterator = bottomOne.iterator(); while (bottomOneIterator.hasNext()) { System.out.println("降雨量最低的城市" + bottomOneIterator.next().getCityName()); } } }
City类:
/** * Created by wenniuwuren on 2015/6/4. */ public class City { private String cityName; private Integer population; private Double averageRainfall; public City(String cityName, Integer population, Double averageRainfall) { this.cityName = cityName; this.population = population; this.averageRainfall = averageRainfall; } public String getCityName() { return cityName; } public void setCityName(String cityName) { this.cityName = cityName; } public Integer getPopulation() { return population; } public void setPopulation(Integer population) { this.population = population; } public Double getAverageRainfall() { return averageRainfall; } public void setAverageRainfall(Double averageRainfall) { this.averageRainfall = averageRainfall; } }
CityByRainfall类:
import com.google.common.primitives.Doubles; import java.util.Comparator; public class CityByRainfall implements Comparator<City> { @Override public int compare(City city1, City city2) { return Doubles.compare(city1.getAverageRainfall(), city2.getAverageRainfall()); } }
输出结果:
Concurrent并发:
Guava在JDK1.5的基础上, 对并发包进行扩展, 有一些是易用性的扩展(如Monitor), 有一些是功能的完善(如ListenableFuture), 再加上一些函数式编程的特性, 使并发包的灵活性极大的提升...
Monitor的使用:
import com.google.common.util.concurrent.Monitor; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; /** * Monitor类语义和 synchronized 或者 ReentrantLocks是同样的, 只容许一个线程进入 */ public class MonitorSample { private static final int MAX_SIZE = 3; private Monitor monitor = new Monitor(); private List<String> list = new ArrayList<String>(); Monitor.Guard listBelowCapacity = new Monitor.Guard(monitor) { @Override public boolean isSatisfied() { return list.size() < MAX_SIZE; } }; public void addToList(String item) throws InterruptedException { // 超过MAX_SIZE, 会锁死 //monitor.enterWhen(listBelowCapacity); // 超过返回false 不会锁死 Boolean a = monitor.tryEnterIf(listBelowCapacity); try { list.add(item); } finally { // 确保线程会推出Monitor锁 monitor.leave(); } } public static void main(String[] args) { MonitorSample monitorSample = new MonitorSample(); for (int count = 0; count < 5; count++) { try { monitorSample.addToList(count + ""); } catch (Exception e) { System.out.println(e); } } Iterator iteratorStringList = monitorSample.list.iterator(); while (iteratorStringList.hasNext()) { System.out.println(iteratorStringList.next()); } } }
Future的扩展: 可识别的返回结果, 可改变的返回结果:
package com.wenniuwuren.listenablefuture; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; /** * 在使用ListenableFuture前, 最好看下JDK的Future使用 * * @author wenniuwuren * */ public class ListenableFutureTest { public static void main(String[] args) { // Guava封装后带有执行结束监放任务执行结束的功能 ExecutorService executorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(5)); ListenableFuture<String> listenableFuture = (ListenableFuture<String>) executorService .submit(new Callable<String>() { public String call() throws Exception { return "task success "; } }); /* Futrue初始版本 // JDK 自带线程池 //ExecutorService executor = Executors.newCachedThreadPool(); // JDK Future Future<Integer> future = executor.submit(new Callable<Integer>() { public Integer call() throws Exception { return 1; } }); // JDK Future真正获取结果的地方 try { Integer count = future.get(); } catch (Exception e) { e.printStackTrace(); }*/ /* listenableFuture 结束监听版本 // 相比JDK的Future等待结果, Guava采用监听器在任务完成时调用 // 可是有个缺陷, 对最后完成的结果无法对操做成功/失败进行处理, 即run方法没返回值 listenableFuture.addListener(new Runnable() { @Override public void run() { System.out.println("运行完成"); } }, executorService);*/ // 运行成功,将会返回 "task success successfully" 解决了listenableFuture 结束监听版本不能对结果进行操做问题 FutureCallbackImpl callback = new FutureCallbackImpl(); // 和计算结果同步运行 //Futures.addCallback(listenableFuture, callback); //若是计算较大, 结果的访问使用异步 将会使用executorService线程去异步执行 Futures.addCallback(listenableFuture, callback, executorService); System.out.println(callback.getCallbackResult()); } } class FutureCallbackImpl implements FutureCallback<String> { private StringBuilder builder = new StringBuilder(); @Override public void onSuccess(String result) { builder.append(result).append("successfully"); } @Override public void onFailure(Throwable t) { builder.append(t.toString()); } public String getCallbackResult() { return builder.toString(); } }
Files文件操做:
文件的复制、重命名、内容读取等对文件的基本操做:
import com.google.common.base.Charsets; import com.google.common.collect.Lists; import com.google.common.hash.HashCode; import com.google.common.hash.Hashing; import com.google.common.io.*; import java.io.*; import java.nio.charset.Charset; import java.util.List; /** * Created by wenniuwuren on 2015/6/16. */ public class FilesTest { public static void main(String[] args) { try { FilesTest filesTest = new FilesTest(); // 一个文件内容复制到另外一个文件中 /*File original = new File("E:\\test\\original"); File copy = new File("E:\\test\\copy"); if (original.isFile() && copy.isFile()) { Files.copy(original, copy); }*/ // 文件重命名 /* File originalFile = new File("E:\\test\\1.txt"); File newFile = new File("E:\\test\\2.txt"); if (originalFile.isFile() && newFile.isFile()) { Files.move(originalFile, newFile); }*/ // 将文件内容一行一行读取出来 File file = new File("E:\\test\\1.txt"); List<String> expectedLines = Lists.newArrayList("The quick brown", " fox jumps over", " the lazy dog"); List<String> readLines = Files.readLines(file, Charsets.UTF_8); System.out.printf(readLines.toString()); // 为文件生成一个hashcode HashCode hashCode = Files.hash(file, Hashing.md5()); System.out.println(hashCode); // 文件 写/新增内容 彻底不用去关心打开打开流/关闭流 String hamletQuoteStart = "To be, or not to be"; Files.write(hamletQuoteStart, file, Charsets.UTF_8); String hamletQuoteEnd = "that is a question"; Files.append(hamletQuoteEnd, file, Charsets.UTF_8); // Sources读 Sinks写 // Sources 和 Sinks 不是 streams', readers', 或者 writers' 对象 // 可是提供相同功能 File dest = new File("E:\\test\\2.txt"); //dest.deleteOnExit(); File source = new File("E:\\test\\1.txt"); ByteSource byteSource = Files.asByteSource(source); ByteSink byteSink = Files.asByteSink(dest); byteSource.copyTo(byteSink); System.out.println(byteSink + ", " + byteSource); // 把几个文件内容写到同一个文件下 File f1 = new File("E:\\test\\1.txt"); File f2 = new File("E:\\test\\2.txt"); File f3 = new File("E:\\test\\3.txt"); File joinedOutput = new File("E:\\test\\4.txt"); //joinedOutput.deleteOnExit(); // 为每一个文件生成InputSupplier(使用Closer去管理关闭底层I/O资源) List<InputSupplier<InputStreamReader>> inputSuppliers = filesTest.getInputSuppliers(f1, f2, f3); // 逻辑上合并为一个InputSupplier InputSupplier<Reader> joinedSupplier = CharStreams.join(inputSuppliers); // 创建输出 OutputSupplier<OutputStreamWriter> outputSupplier = Files.newWriterSupplier(joinedOutput, Charsets.UTF_8); // 将底层InputSuppliers写到OutputSupplier CharStreams.copy(joinedSupplier, outputSupplier); } catch (IOException e) { e.printStackTrace(); } } private String joinFiles(File... files) throws IOException { StringBuilder builder = new StringBuilder(); for (File file : files) { builder.append(Files.toString(file, Charsets.UTF_8)); } return builder.toString(); } private List<InputSupplier<InputStreamReader>> getInputSuppliers(File... files) { List<InputSupplier<InputStreamReader>> list = Lists.newArrayList(); for (File file : files) { list.add(Files.newReaderSupplier(file, Charsets.UTF_8)); } return list; } }