这里抛砖引玉列出Guava一些常用工具类,更多用法请自行挖掘。
Guava Cache是一个全内存的本地缓存实现,它提供了线程安全的实现机制。
cache的常用参数:
1. 缓存最大大小的设置:CacheBuilder.maximumSize(long)
2. 过期时间:expireAfterAccess(long, TimeUnit) expireAfterWrite(long, TimeUnit)
3. 引用类型:CacheBuilder.weakKeys() CacheBuilder.weakValues() CacheBuilder.softValues()
4. 自动刷新cache:CacheBuilder.refreshAfterWrite
5. 过期时间:CacheBuilder.expireAfterWrite
LoadingCache cache = CacheBuilder.newBuilder()
.maximumSize(10).refreshAfterWrite(10, TimeUnit.MINUTES)
.softValues() //软引用
.expireAfterWrite(1, TimeUnit.DAYS)
.build(new CacheLoader() {
@Override
public BigDecimal load(String key) throws Exception {
return new BigDecimal(0);
}
});
Joiner 可以快速地把多个字符串或字符串数组连接成为用特殊符号连接的字符串。
List list = Lists.newArrayList("a","b","c");
String value =Joiner.on("-").skipNulls().join(list);
System.out.println(value);
//输出为: a-b-c
String testString = "Monday,Tuesday,,Thursday,Friday,,";
//英文分号分割;忽略空字符串
Splitter splitter = Splitter.on(",").omitEmptyStrings().trimResults();
System.out.println(splitter.split(testString).toString());
//转换为了:[Monday, Tuesday, Thursday, Friday]
String value = CharMatcher.DIGIT.retainFrom("some text 2046 and more");
//value=2046
List<String> list =Lists.newArrayList();
List<String> list2 = Lists.newArrayList("a","b","c");
Set<Integer> set = Sets.newHashSet();
类型推导的功能,在Java 7中已经得到支持。
Map<String,List<String>> m=new HashMap<>();
可以返回原返回类型的任何子类型的对象
Maps.newHashMap();
Maps.newLinkedHashMap();
List listStr = Lists.newArrayList("1", "2", "3");
//将字符串集合转换为Integer集合
List listInteger = Lists.transform(listStr, new Function() {
@Nullable
@Override
public Integer apply(@Nullable String s) {
return Integer.valueOf(s);
}
});
在Java 8中的实现为
List listInteger2 = listStr.stream().map(Integer::valueOf).collect(Collectors.toList());
Iterables.find查找集合首个匹配的元素
List<String> listStr = Lists.newArrayList("hello", "world", "hehe");
//查找首个以h开头的值
String value = Iterables.find(listStr, new Predicate<String>() {
@Override
public boolean apply(String input) {
return input.startsWith("h");
}
});
在Java 8中的实现为
String value2 = listStr.stream().findFirst().filter(input -> input.startsWith("h")).get();
Collections2.filter过滤集合中所有符合特定条件的元素。
List listWithH = Lists.newArrayList(Collections2.filter(listStr, new Predicate() {
@Override
public boolean apply(@Nullable String s) {
return s.startsWith("h");
}
}));
在Java 8中的实现为
List listWithH2 = listStr.stream().filter(input -> input.startsWith("h")).collect(Collectors.toList());
Lists.partition可以将一个大的集合分割成小集合,适用于分批查询、插入等场景。
List listStr = Lists.newArrayList("1", "2", "3","4","5","6","7");
List> batchList = Lists.partition(listStr,3);
//被分割成了: [[1, 2, 3], [4, 5, 6], [7]]
class Apple {
int id;
String color;
public Apple(int id, String color) {
this.id = id;
this.color = color;
}
public int getId() {
return id;
}
public String getColor() {
return color;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(Apple.class).add("id", id).add("color", color).toString();
}
}
@Test
public void test1() {
List appleList = Lists.newArrayList(new Apple(1, "red"), new Apple(2, "red"), new Apple(3, "green"), new Apple(4, "green"));
// 以主键为key,生成键值对:Map
Map appleMap = Maps.uniqueIndex(appleList, new Function() {
@Nullable
@Override
public Integer apply(@Nullable Apple apple) {
return apple.getId();
}
});
// 相当于根据颜色分类:转为Map<颜色,Collection>
Multimap multiMap = Multimaps.index(appleList,
new Function() {
@Nullable
@Override
public String apply(@Nullable Apple apple) {
return apple.getColor();
}
});
}
在Java 8中的实现为
List appleList = Lists.newArrayList(new Apple(1, "red"), new Apple(2, "red"), new Apple(3, "green"), new Apple(4, "green"));
Map appleMap = appleList.stream().collect(Collectors.toMap(Apple::getId, apple -> apple));
Map> groupsByColor =
appleList.stream().collect(Collectors.groupingBy(Apple::getColor));
排序:
Collections.sort
Ordering.natural()
集合的交集、并集和差集:
Sets.intersection(setA, setB);
Sets.union(setA, setB);
Sets.difference(setA, setB);
创建不可变的集合
ImmutableList<String> list = ImmutableList.of("1", "2", "3");
com.google.common.util.concurrent目录下是各种线程工具类。
这里介绍一下:
ListenableFuture:顾名思义就是可以监听的Future,它是对java原生Future的扩展增强。
MoreExecutors:该工具类,提供了很多静态方法。其中listeningDecorator方法初始化ListeningExecutorService方法,使用此实例submit方法即可初始化ListenableFuture对象。
ListeningExecutorService的invokeAny继承自Jdk原生类,率先返回线程组中首个执行完毕的。
ListeningExecutorService的invokeAll并行执行线程组,等待所有线程执行完毕,适用于批量处理。
public final List list = Lists.newArrayList("a", "b", "c", "d", "e", "f");
@Test
public void testGuava() {
ListeningExecutorService listeningExecutorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
List> allThread = Lists.newArrayList();
for (final String value : list) {
Callable callable = new Callable() {
@Override
public String call() {
return value + " 休息了 " + sleepRandom();
}
};
allThread.add(callable);
}
try {
//1. 返回首个执行完毕的值
// String date = listeningExecutorService.invokeAny(allThread);
// 2. 并行执行完所有线程
List> valueList = listeningExecutorService.invokeAll(allThread);
for (Future future : valueList) {
System.out.println(future.get());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
listeningExecutorService.shutdown();
}
}
在Java 8中可以这样实现
@Test
public void testJava8() throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(10);
List futures = list.stream()
.map(value -> CompletableFuture.completedFuture(value).thenApplyAsync(s -> s + " 休息了 " + sleepRandom(), executor))
.collect(Collectors.toList());
//1. 返回首个执行完毕的值
// CompletableFuture valueFuture = CompletableFuture.anyOf(futures.toArray(new CompletableFuture[futures.size()]));
// 2. 并行执行完所有线程
CompletableFuture valueFutureList = CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]));
futures.stream().forEach(f -> {
try {
System.out.println(f.get());
} catch (Exception e) {
}
});
}
EventBus是Guava提供的消息发布-订阅类库,它的工作机制类似于观察者模式,通过通知者去注册观察者,最后由通知者向观察者发布消息。
如果你需要订阅某种类型的消息,只需要在指定的方法上加上@Subscribe注解即可。
代码例子:
一个观察者可以订阅多个发布者,一个发布者可以推送给多个观察者,实现了解耦。
public class MqEvent {
}
public class StatusEvent {
}
//第一个观察者,订阅了两种类型的发布
public class EventHandler {
@Subscribe
public void mq(MqEvent mq) {
System.err.println(mq.getClass().getCanonicalName()+" work");
}
@Subscribe
public void status(StatusEvent statusEvent) {
System.err.println(statusEvent.getClass().getCanonicalName() +" work");
}
}
// 第二个观察者只订阅了一种类型的发布
public class OtherHandler {
@Subscribe
public void mq(MqEvent mq) {
System.err.println( "OtherHandler work");
}
}
public class EventTest {
public static void main(String[] args) {
//初始化消息总线
EventBus eventBus = new EventBus();
// 注册订阅者
eventBus.register(new EventHandler());
eventBus.register(new OtherHandler());
//MqEvent推送给了两个订阅者
MqEvent mqEvent = new MqEvent();
StatusEvent statusEvent = new StatusEvent();
//发布消息
eventBus.post(mqEvent);
eventBus.post(statusEvent);
}
}
EventBus 另有异步实现: AsyncEventBus
另一个更加专业、更加强大、更加高效,基于内存的消息处理框架是来自LMAX(伦敦外汇黄金交易所)的:Disruptor
我们经常使用System.currentTimeMillis()来计算某段代码执行的实现,Stopwatch 可以很方便的实现同样的功能。
Stopwatch stopwatch = Stopwatch.createStarted();
for(int i =0; i <10000; i++){
//do something test
}
long nanos = stopwatch.elapsed(TimeUnit.NANOSECONDS);
System.out.println(nanos);
了解一下Guava中激动人心的算法。详情自行搜索。
布隆过滤器用于判断一个元素是否在一个超大的集合中。
哈希表也能用于判断元素是否在集合中,但是布隆过滤器只需要哈希表的1/8或1/4的空间复杂度就能完成同样的功能。
Guava中的布隆过滤实现:
com.google.common.hash.BloomFilter
com.google.common.util.concurrent.RateLimiter