文章目录
前言
Guava 是谷歌开源的 Java 核心库,它包括很多新的集合类型(如 multimap 和 multiset)、不可变集合、graph 库,以及用于并发、I/O、哈希、缓存、基本类型、字符串等的实用代码!它被广泛应用于谷歌中的大多数 Java 项目中,也被许多其他公司广泛使用。
github 地址:https://github.com/google/guava
api doc 地址:https://guava.dev/releases/snapshot-jre/api/docs/
pom 依赖:
<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>31.1-jre</version></dependency>
gauva 所有包如下:
包名用处com.google.common.annotationsguava 一些注解com.google.common.base基本相关com.google.common.cache缓存相关程序com.google.common.collect集合类接口相关com.google.common.escapeescapers and encoderscom.google.common.eventbusEventBus 实现组件之间进行发布-订阅方式通讯com.google.common.graph图(点和边)相关com.google.common.hash哈希相关com.google.common.htmlEscapers for HTMLcom.google.common.ioIO 相关com.google.common.math数学相关com.google.common.net网络地址(IP和域名)相关com.google.common.primitives基本类型相关com.google.common.reflect反射相关com.google.common.util.concurrent并发相关com.google.common.xmlEscapers for XML.
一、基本
1.1 数据校验
int i =-1;Preconditions.checkArgument(i >=0,"Argument was %s but expected nonnegative", i);Preconditions.checkNotNull(i,"i should not null");
1.2 字符串
官方测试类:
- https://github.com/google/guava/blob/master/guava-tests/test/com/google/common/base/StringsTest.java
- https://github.com/google/guava/blob/master/guava-tests/test/com/google/common/base/JoinerTest.java
- https://github.com/google/guava/blob/master/guava-tests/test/com/google/common/base/SplitterTest.java
@TestpublicvoidstringsTest(){assertThat(Strings.commonPrefix("ab","abc"),is("ab"));assertThat(Strings.lenientFormat("hello %s demo","world"),is("hello world demo"));assertThat(Strings.nullToEmpty(null),is(""));assertThat(Strings.repeat("ab",5),is("ababababab"));assertThat(Strings.emptyToNull(""),is(nullValue()));assertThat(Strings.isNullOrEmpty(""),is(true));// 返回一个长度至少为 3 的字符串,该字符串由前缀为 '0' 的多份复制的字符串组成,以达到该长度assertThat(Strings.padStart("7",3,'0'),is("007"));// 返回一个长度至少为 3 的字符串,该字符串由后缀为 '0' 的多份复制的字符串组成,以达到该长度assertThat(Strings.padEnd("7",3,'0'),is("700"));Joiner joiner =Joiner.on("; ").skipNulls();assertThat(joiner.join("A",null,"C","D"),is("A; C; D"));Iterable<String> split =Splitter.on(',').trimResults().omitEmptyStrings().split("foo,bar,, qux");assertThat(Lists.newArrayList(split),is(Lists.newArrayList("foo","bar","qux")));}
1.3 异常
@TestpublicvoidexceptionTest(){String s =Throwables.getStackTraceAsString(newNullPointerException("不能为空"));String exceptionStr ="java.lang.NullPointerException: 不能为空";assertThat(s,is(containsString(exceptionStr)));}
1.4 变量类名转换
CaseFormat
官方测试类:https://github.com/google/guava/blob/master/guava-tests/test/com/google/common/base/CaseFormatTest.java
枚举含义例子LOWER_CAMELJava变量的命名规则lowerCamelLOWER_HYPHEN连字符连接变量的命名规则lower-hyphenLOWER_UNDERSCOREC ++变量命名规则lower_underscoreUPPER_CAMELJava和C++类的命名规则UpperCamelUPPER_UNDERSCOREJava和C++常量的命名规则UPPER_UNDERSCORE
@TestpublicvoidcaseformatTest(){String s1 =CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL,"low_exception");assertThat(s1,is("lowException"));String s2 =CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE,"lowException");assertThat(s2,is("low_exception"));String s3 =CaseFormat.LOWER_HYPHEN.to(CaseFormat.LOWER_UNDERSCORE,"low-exception");assertThat(s3,is("low_exception"));String s4 =CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL,"low-exception");assertThat(s4,is("LowException"));String s5 =CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_UNDERSCORE,"low-exception");assertThat(s5,is("LOW_EXCEPTION"));}
二、缓存
2.1 基本使用
Cache<String,String> cache =CacheBuilder.newBuilder()// 最大3个.maximumSize(3).build();
cache.put("1","helloworld");
cache.put("2","dong");
cache.put("3","san");
logger.info("{}", cache.asMap());
cache.invalidate("1");String first = cache.getIfPresent("1");
logger.info("{}, {}", first, cache.asMap());
2.2 淘汰策略
- 未访问数据,淘汰策略是FIFO, 访问数据后,淘汰策略是LRU + FIFO
Cache<String,String> cache =CacheBuilder.newBuilder()// 最大3个.maximumSize(3).build(); cache.put("1","helloworld"); cache.put("2","dong"); cache.put("3","san"); logger.info("{}", cache.asMap()); cache.put("4","wu"); logger.info("{}", cache.asMap()); cache.invalidateAll(); cache.put("1","helloworld"); cache.put("2","dong"); cache.put("3","san");String first = cache.getIfPresent("1"); cache.put("4","www"); logger.info("{}", cache.asMap());
- 过期时间失效, expireAfterAccess 包含创建、读取、替换,而 expireAfterWrite 只包含创建、替换
Cache<String,String> cache =CacheBuilder.newBuilder()// 最大3个.maximumSize(3)// 访问(创建,读取,替换)后3s失效.expireAfterAccess(3,TimeUnit.SECONDS)// 删除监听器.removalListener((a)->System.out.println(a.getKey()+":"+ a.getValue()+","+ a.getCause())).build(); cache.put("1","helloworld"); cache.put("2","dong"); cache.put("3","san"); logger.info("{}", cache.asMap());TimeUnit.SECONDS.sleep(4); logger.info("{}", cache.asMap()); cache.put("4","4"); cache.put("5","5");TimeUnit.SECONDS.sleep(2); logger.info("{}", cache.asMap());String s = cache.getIfPresent("4");TimeUnit.SECONDS.sleep(2); logger.info("{}", cache.asMap());
2.3 统计
cache 可统计 命中数量、miss 数量、删除数量、加载时间、命中率等
Cache<String,String> cache =CacheBuilder.newBuilder()// 最大3个.maximumSize(3)// 统计功能.recordStats().expireAfterAccess(3,TimeUnit.SECONDS).build();
cache.put("1","helloworld");
cache.put("2","dong");
cache.put("3","san");String s = cache.getIfPresent("1");
logger.info("{}", cache.asMap());TimeUnit.SECONDS.sleep(4);
logger.info("{}", cache.asMap());String s1 = cache.getIfPresent("121");
cache.cleanUp();CacheStats stats = cache.stats();
logger.info("{}, {}, {}", stats.evictionCount(), stats.hitCount(), stats.hitRate());
三、集合
3.1 集合工厂
@TestpublicvoidcollectionTest(){ArrayList<Integer> list =Lists.newArrayList(1,2,3);List<List<Integer>> partition =Lists.partition(list,2);List<Integer> reverseList =Lists.reverse(list);assertThat(partition,is(Lists.newArrayList(Lists.newArrayList(1,2),Lists.newArrayList(3))));assertThat(reverseList,is(Lists.newArrayList(3,2,1)));HashSet<Integer> set1 =Sets.newHashSet(1,2,3,4,5);HashSet<Integer> set2 =Sets.newHashSet(1,3,5,7,9);Sets.SetView<Integer> difference =Sets.difference(set1, set2);assertThat(Sets.newHashSet(difference),is(Sets.newHashSet(2,4)));Sets.SetView<Integer> intersection =Sets.intersection(set1, set2);assertThat(Sets.newHashSet(intersection),is(Sets.newHashSet(1,3,5)));HashMap<String,String> map =Maps.newHashMap();Map<Integer,String> asMap =Maps.asMap(set1, s -> s +""+ s);Map<Integer,String> totalMap = set1.stream().collect(Collectors.toMap(Function.identity(), v -> v +""+ v));assertThat(asMap,is(totalMap));}
3.2 不可变对象
Immutable Object 就是一旦创建,就不能再被更改的对象。对 Immutable Object的任何修改或添加删除操作都会返回一个新的 Immutable Object。guava 中不可变类以 Immutable 起始,下面是常见的类
- ImmutableSet
- ImmutableList
- ImmutableMap
@TestpublicvoidimmutableSetTest(){Integer i =1;ImmutableSet<Integer> set =ImmutableSet.of(i,3,5,7,9); i =-1;assertThat(set,is(ImmutableSet.copyOf(Sets.newHashSet(1,3,5,7,9))));}
3.3 HashMultiset
HashMultiset 可以统计加入 set 中元素数量
List<String> arrayList =Lists.newArrayList("1","1","2","2","3","3");HashMultiset<String> multiset =HashMultiset.create(arrayList);
multiset.elementSet().forEach(s -> logger.info("{}, {}", s, multiset.count(s)));
3.4 HashMultimap/ArrayListMultimap
HashMultimap 可以将put 重复key的值存入set中,底层是 HashMap<K, HashSet>,如果想要保留 value, 不去重,可以使用ArrayListMultimap,底层是 HashMap<K, ArrayList>
HashMultimap<Integer,Integer> map =HashMultimap.create();
map.put(2,4);
map.put(1,2);
map.put(1,3);
map.put(2,6);
map.put(2,4);
map.put(11,2);
map.put(12,3);
map.put(21,6);
map.put(6,7);
logger.info("{}", map);
3.5 BiMap
BiMap 是可以保持其值和键都是唯一性的map
BiMap<String,String> biMap =HashBiMap.create();
biMap.put("A","123");
biMap.forcePut("F","123");
biMap.put("B","456");
biMap.put("C","789");
biMap.put("D","4");
biMap.put("E","5");
logger.info("{}", biMap);BiMap<String,String> reBiMap = biMap.inverse();
logger.info("{}", reBiMap);
3.6 Collections2
// 求全排列Collection<List<Integer>> permutations =Collections2.permutations(Lists.newArrayList(1,2,3));
logger.info("{}",Lists.newArrayList(permutations));
四、哈希
4.1 Hashing
@Data@AllArgsConstructorclassDemo{privateLong id;privateString name;}@TestpublicvoidhashTest(){HashFunction hf =Hashing.goodFastHash(12);HashCode hc = hf.newHasher().putLong(100L).putString("张三",Charsets.UTF_8).putObject(newDemo(2L,"李四"),(demo, sink)->{
sink.putLong(demo.getId()).putString(demo.getName(),Charsets.UTF_8);}).hash();
logger.info("{}", hc.hashCode());}
4.2 布隆过滤器
Funnel<Demo> s =(demo, sink)->{
sink.putLong(demo.getId()).putString(demo.getName(),Charsets.UTF_8);};Faker faker =Faker.instance(Locale.CHINA);List<Demo> list = faker.collection(()->newDemo(faker.number().numberBetween(100L,10000L), faker.name().name())).len(500).generate();BloomFilter<Demo> demos =BloomFilter.create(s,500,0.01);for(Demo friend : list){
demos.put(friend);}Demo notExist =newDemo(100L,"test100");Demo exist = list.get(250);
logger.info("{}, {}", demos.mightContain(notExist), demos.mightContain(exist));
五、IO
5.1 文件
@TestpublicvoidioTest()throwsIOException{String filePath ="E:\\tmp\\file.txt";List<String> strings =Files.readLines(Paths.get(filePath).toFile(),Charsets.UTF_8);
logger.info("{}", strings);// 获取文件后缀assertThat(Files.getFileExtension(filePath),is("txt"));// 获取文件名assertThat(Files.getNameWithoutExtension(filePath),is("file"));File file =Paths.get(filePath).toFile();// 读取UTF-8文件ImmutableList<String> lines =Files.asCharSource(file,Charsets.UTF_8).readLines();// 文件单词统计Multiset<String> wordOccurrences =HashMultiset.create(Splitter.on(CharMatcher.whitespace()).trimResults().omitEmptyStrings().split(Files.asCharSource(file,Charsets.UTF_8).read()));// 获取文件 hash 值HashCode hash =Files.asByteSource(file).hash(Hashing.sha256());
logger.info("{} {}", wordOccurrences, hash);// 从 URL复制到文件URL url =newURL("file:\\E:\\tmp\\file.txt");Resources.asByteSource(url).copyTo(Files.asByteSink(newFile("E:\\tmp\\1.txt")));}
5.2 资源
List<String> strings =Resources.readLines(newURL("file:\\D:\\t.txt"),Charsets.UTF_8);
六、基本类型
6.1 Ints/Longs/Floats/Doubles
@TestpublicvoidintsTest(){Integer i1 =Ints.tryParse("10101001",2);int i2 =Ints.max(1,-1,0,-2,3,100,999);int i3 =Ints.min(1,-1,0,-2,3,100,999);String s =Ints.join(",",0,1,2,3,4,5);int i4 =Ints.checkedCast(100000000L);assertThat(Longs.numberOfLeadingZeros(20000L),is(49));assertThat(Longs.numberOfTrailingZeros(2000L),is(4));}
6.2 UnsignedInts
@TestpublicvoidunsignedIntsTest(){int max =UnsignedInts.max(-1,0,1);assertThat(max,is(-1));}
七、反射
7.1 动态代理
interfaceDemoTest{DemoTestadd(int a);intresult();}classCustomInvokeHandlerimplementsInvocationHandler{int ans =0;@OverridepublicObjectinvoke(Object proxy,Method method,Object[] args)throwsThrowable{if(method.getName().equals("add")){
ans +=(int)args[0];return proxy;}return ans;}}@TestpublicvoidreflectTest(){DemoTest test =Reflection.newProxy(DemoTest.class,newCustomInvokeHandler());int result = test.add(1).add(2).add(3).add(100).result();assertThat(result,is(106));}
7.2 泛型类型获取
List list =newArrayList<String>(){};Type superclass = list.getClass().getGenericSuperclass();ParameterizedType parameterized =(ParameterizedType) superclass;Type raw = parameterized.getRawType();Type[] types = parameterized.getActualTypeArguments();
logger.info("{},{}", raw, types);
7.3 Invokable
@TestpublicvoidreflectTest()throwsNoSuchMethodException{Method method =String.class.getMethod("length");Invokable invokable =Invokable.from(method);assertThat(invokable.isPublic(),is(true));assertThat(invokable.isPackagePrivate(),is(false));assertThat(invokable.isOverridable(),is(false));assertThat(invokable.getParameters().size(),is(0));assertThat(invokable.getReturnType().getRawType(),is(int.class));}
7.4 ClassPath
ClassPath classPath =ClassPath.from(this.getClass().getClassLoader());for(ClassPath.ClassInfo classInfo : classPath.getTopLevelClasses("com.aabond.guava")){
logger.info("{}", classInfo);}
八、并发
8.1 ThreadFactoryBuilder
ThreadFactoryBuilder 提供生成 ThreadFactory 的 Builder,提供方法设置 后台线程,命名格式化,线程优先级,未捕获异常处理器,线程工厂等
ThreadFactory factory =newThreadFactoryBuilder().setNameFormat("guava-thread-%d").build();Thread test1 = factory.newThread(()->{try{TimeUnit.SECONDS.sleep(2);}catch(InterruptedException e){thrownewRuntimeException(e);}
logger.info("{}, {}",Thread.currentThread().getName(),Thread.activeCount());});
test1.start();
test1.join();
8.2 ListenableFuture/Futures
ListenableFuture 顾名思义就是能够监听的 Future ,它是对 java 原生 Future 的扩展加强。传统的 Future 表示一个异步计算的结果,ListenableFuture 允许在计算成功后或失败后执行回调方法
Futures 提供一些方法来操纵 ListenableFuture
ListeningExecutorService service =MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));ListenableFuture<Integer> task1 = service.submit(()->{try{TimeUnit.SECONDS.sleep(2);}catch(InterruptedException e){thrownewRuntimeException(e);}
logger.info("{} invoke",Thread.currentThread().getName());return1;// throw new NullPointerException();});FutureCallback<Integer> callback =newFutureCallback<Integer>(){@OverridepublicvoidonSuccess(Integer result){
logger.info("success result = {}", result);}@OverridepublicvoidonFailure(Throwable t){
logger.info("failure exception = {}", t);}};Futures.addCallback(task1, callback, service);try{TimeUnit.SECONDS.sleep(3);}catch(InterruptedException e){thrownewRuntimeException(e);}
参考
- https://github.com/google/guava/wiki
- 0318 guava并发工具
版权归原作者 aabond 所有, 如有侵权,请联系我们删除。