0


Java开源工具库使用之Guava

文章目录

前言

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 数据校验

官方测试类:https://github.com/google/guava/blob/master/guava-tests/test/com/google/common/base/PreconditionsTest.java

int i =-1;Preconditions.checkArgument(i >=0,"Argument was %s but expected nonnegative", i);Preconditions.checkNotNull(i,"i should not null");

1.2 字符串

官方测试类:

@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 异常

官方测试类:https://github.com/google/guava/blob/master/guava-tests/test/com/google/common/base/ThrowablesTest.java

@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"));}

二、缓存

官方测试类:https://github.com/google/guava/blob/master/guava-tests/test/com/google/common/cache/CacheBuilderTest.java

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 + FIFOCache<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);}

参考

  1. https://github.com/google/guava/wiki
  2. 0318 guava并发工具

本文转载自: https://blog.csdn.net/qq_23091073/article/details/127497092
版权归原作者 aabond 所有, 如有侵权,请联系我们删除。

“Java开源工具库使用之Guava”的评论:

还没有评论