您的位置:首页 > 其它

GUAVA常用方法总结整理(list map string concurrent file)

2016-09-17 00:00 127 查看
1.对字符串的操作:

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迭代器:

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矩阵

使用Guava对矩阵的实现, 做一些矩阵存贮等操作将大大提高效率, 而不是自己用JDK的Array去实现, 可能带来不少bug, 而且增加代码复杂度。

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、 键值对反转等

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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  guava list map concurrent