一、guava的简介
工具类 就是封装平常用的方法,不需要你重复造轮子,节省开发人员时间,提高工作效率。
- 高效设计良好的API,被Google的开发者设计,实现和使用
- 遵循高效的java语法实践
- 使代码更刻度,简洁,简单
- 节约时间,资源,提高生产力 Guava工程包含了若干被Google的 Java项目广泛依赖 的核心库,例如:
- 集合 [collections]
- 缓存 [caching]
- 原生类型支持 [primitives support]
- 并发库 [concurrency libraries]
- 通用注解 [common annotations]
- 字符串处理 [string processing]
- I/O 等等。
二、guava的应用
·2.1引用maven denpendency
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>20.0</version>
</dependency>
·2.2相关操作包的应用
基本工具包Base
·Optional
类似于java8中的Optional,都是对Null相关的操作。在guava中Optional是抽象类,具体的实现类是Absent和Present,而java.util是final类。其他的部分的方法名是相同的。
在guava中使用Optional来表示可能为null的引用。
public class GuavaDemoApplication {
public static void main(String[] args) {
Integer s1 = null;
Integer s2 = 10;
Optional<Integer> s1OP = Optional.fromNullable(s1);
Optional<Integer> s2OP = Optional.of(s2);
System.out.println("sum() = "+sum(s1OP,s2OP));
SpringApplication.run(GuavaDemoApplication.class, args);
}
public static Integer sum(Optional<Integer> a,Optional<Integer> b){
System.out.println("a is present -> "+a.isPresent());
System.out.println("b is present -> "+b.isPresent());
Integer Va = a.or(0);
Integer Vb = b.get();
return Va+Vb;
}
}
注意:在使用get()方法时一般配合着isPresent()方法使用,避免get不到具体的实例。
·Preconditions
·Joiner
System.out.println(Joiner.on(",").withKeyValueSeparator("=").join(stringMap));
·Splitter
spltter能够按照给定的分割符将字符串分割成能够进行迭代输出的集合Iterable
/* on():指定分隔符来分割字符串
limit():当分割的子字符串达到了limit个时则停止分割
fixedLength():根据长度来拆分字符串
trimResults():去掉子串中的空格
omitEmptyStrings():去掉空的子串
withKeyValueSeparator():要分割的字符串中key和value间的分隔符,分割后的子串中key和value间的分隔符默认是= */
guava发布的事件默认不会处理线程安全的,但是我们可以通过标注注解@AllowConcurrentEvents来保证其线程安全。
eg:1、)创建一个普通的POJO作为我们的消息事件对象
2、)创建订阅对象,通过标注@Subscribe来保证有且只有只有一个输入参数,如果需要订阅某种类型的消息,只需要在指定的方法上添加@Subscrube注解。一个subscriber可以同时有多个订阅事件,guava会通过事件类型和订阅方法的形参来确定到底采用哪一个订阅方法。
·Collection
不可变集合,不可变集合对象的好处:
- 当对象被不可信的库调用时,不可变形式是安全的;
- 不可变对象被多个线程调用时,不存在竞态条件问题
不可变集合不需要考虑变化,因此可以节省时间和空间。所有不可变的集合都比它们的可变形式有更好的内存利用率(分析和测试细节);
不可变对象因为有固定不变,可以作为常量来安全使用。
如何创建不可变对象;
copyOf()方法,如ImmutableSet.copyOf(set);
of()方法,如ImmutableSet.of(“a”, “b”, “c”)或 ImmutableMap.of(“a”, 1, “b”, 2);
Builder工具,如ImmutableSet<String> set=ImmutableSet.<String>builder().addAll(someSet).add("e").build();
·Collection2
filter():只保留集合中满足特定要求的元素。延伸:结合java 8中的lamda表达式进行操作,对比于利用原生lamda表达式和stream流式操作实现集合的求并集、交集和差集。
eg:Collection2.filter(list,input->{return new StringBulider(input).reverse().toString().equals(input);})
transform():类型转换
eg:Conllection<String> times = Collections2.transform(times,new Function<Long,String>{
@Nullable
@Override
public String apply(@Nullable Long input){
return new SimpleDateFormat("yyyy-MM-dd").format(input);
}
sout(times);
});
集合求并集、交集、差集。
Sets.SetView<Integer> inter=Sets.intersection(set1,set2); //交集
System.out.println(inter);
Sets.SetView<Integer> diff=Sets.difference(set1,set2); //差集,在A中不在B中
System.out.println(diff);
Sets.SetView<Integer> union=Sets.union(set1,set2); //并集
ListenableFuture
传统JDK中的Future通过异步的方式计算返回结果:在多线程运算中可能或者可能在没有结束返回结果,Future是运行中的多线程的一个引用句柄,确保在服务执行返回一个Result。
ListenableFuture可以允许你注册回调方法(callbacks),在运算(多线程执行)完成的时候进行调用, 或者在运算(多线程执行)完成后立即执行。这样简单的改进,使得可以明显的支持更多的操作,这样的功能在JDK concurrent中的Future是不支持的。
public class ListenableFutureDemo {
public static void main(String[] args) {
//将ExecutorService装饰成ListeningExecutorService
ListeningExecutorService service= MoreExecutors.listeningDecorator(
Executors.newCachedThreadPool());
//通过异步的方式计算返回结果
ListenableFuture<String> future=service.submit(() -> {
System.out.println("call execute..");
return "task success!";
});
//有两种方法可以执行此Future并执行Future完成之后的回调函数
future.addListener(() -> { //该方法会在多线程运算完的时候,指定的Runnable参数传入的对象会被指定的Executor执行
try {
System.out.println("result: "+future.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
},service);
Futures.addCallback(future, new FutureCallback<String>() {
@Override
public void onSuccess(@Nullable String result) {
System.out.println("callback result: "+result);
}
@Override
public void onFailure(Throwable t) {
System.out.println(t.getMessage());
}
},service);
}
}