GUAVA經常使用方法總結整理(list map string concurrent file)

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

Range範圍過濾

本文介紹了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;
	}
}

輸出結果:

Ordering排序工具

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;
    }
}
相關文章
相關標籤/搜索