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