谷歌核心库_java常用utils工具类

谷歌核心库_java常用utils工具类目录com.google.common.collect.Lists工具类com.google.common.primitives.Ints整形操作com.google.common.colle

谷歌核心库_java常用utils工具类"

目录

Google Guava 概述

不可变集合与对象

Guava 新集合类型

JDK 集合辅助工具类

JDK 基本类型辅助工具类

JDK 字符串辅助工具类

Stopwatch 秒表

RateLimiter 限速器/限流器

ListenableFuture 异步线程侦听器


Google Guava 概述

1、Guava 是一组来自 Google 的核心 Java 库,包括新的集合类型(如 multimap 和 multiset)、不可变集合、图形库以及用于并发、I/O、散列、缓存、原语、字符串等的实用程序!被广泛应用于 Google 的大多数 Java 项目中,也被许多其他公司广泛使用。

2、guava github 开源地址:GitHub – google/guava: Google core libraries for Java

3、官网用户手册:https://github.com/google/guava/wiki

4、com.google.guava 依赖:

<dependency>
  <groupId>com.google.guava</groupId>
  <artifactId>guava</artifactId>
  <version>29.0-jre</version>
</dependency>

不可变集合与对象

1、制作对象的不可变副本是一种很好的防御性编程技术,不可变对象有许多优点,包括:

可供不受信任的库安全使用。

线程安全:可由多个线程使用,无争用风险。

不需要支持突变,并且可以节省时间和空间,所有不可变的集合实现都比它们的可变同级更节省内存。

可以用作常数,并期望它将保持不变。

2、要点:每个 Guava 不可变集合实现都拒绝 null 值。Guava 的设计上推荐使用 null 值,大多数情况下,遇到 null 值会抛异常.

3、一个不可变的 ImmutableXxx 集合可以通过以下几种方式创建:

使用 copyOf 方法,如 ImmutableSet.copyOf(set)

使用 of 方法, 如 ImmutableSet.of("a", "b", "c")ImmutableMap.of("a", 1, "b", 2)

使用 Builder 方法,。

4、Guava 为 java jdk 每种标准集合类型提供了简单易用的不可变版本包括 Guava 自己的集合变体,为 java 提供的不可变版本都是继承 java jdk 的接口而来,所以操作上基本无异。下面接口的实现类也都有对应的不可变版本。

接口 JDK 或者 Guava 不可变版本
Collection JDK ImmutableCollection
List JDK ImmutableList
Set JDK ImmutableSet
SortedSet/NavigableSet JDK ImmutableSortedSet
Map JDK ImmutableMap
SortedMap JDK ImmutableSortedMap
Multiset Guava ImmutableMultiset
SortedMultiset Guava ImmutableSortedMultiset
Multimap Guava ImmutableMultimap
ListMultimap Guava ImmutableListMultimap
SetMultimap Guava ImmutableSetMultimap
BiMap Guava ImmutableBiMap
ClassToInstanceMap Guava ImmutableClassToInstanceMap
Table Guava ImmutableTable

在线演示源码:https://gitee.com/wangmx1993/apache-study/blob/master/src/main/java/com/wmx/guava/ImmutableCollectionTest.java

官网文档:https://github.com/google/guava/wiki/ImmutableCollectionsExplained

Guava 新集合类型

1、Guava 引入了许多新的集合类型,这些类型不在 Java JDK 中,但却非常有用,这些都是为了与 JDK 集合框架愉快地共存而设计的,而不是将东西塞进 JDK 集合抽象中。

Multiset 可重复集合

1、Guava 提供了一个新的集合类型 Multiset,它支持添加多个相同的元素,其中成员可以出现不止一次。

2、Multiset 相当于 Set,区别在于 Multiset 可添加相同的元素,它的内部使用一个 HashMap 来维护,

3、Multiset 也有自己的实现类,常用的有 HashMultiset、LinkedHashMultiset、TreeMultiset 等,HashMultiset 、TreeMultiset 是无序的,LinkedHashMultiset 是有序的,操作完全同理 JDK 的 HashSet、TreeSet、LinkedHashSet。

在线演示源码:https://gitee.com/wangmx1993/apache-study/blob/master/src/main/java/com/wmx/guava/MultisetTest.java

Multimap 多重映射

1、每个有经验的 Java 程序员都曾在某个地方实现过 Map<K、List<V>> 或 Map<K、Set<V>>,Guava 的 Multimap 框架使处理从键到多个值的映射变得容易,多重映射是将键与任意多个值关联的一种通用方法。

2、从概念上讲,有两种方法可以将多重映射视为从单个键到单个值的映射的集合:

			a -> 1		               a -> [1, 2, 4]
			a -> 2                         b -> [3]
	方式1	        a -> 4             方式2       c -> [5]
			b -> 3                          
			c -> 5                          

3、Multimap 提供了多种实现:

Multimap  实现 key 使用的是 value 使用的是
ArrayListMultimap HashMap ArrayList
HashMultimap HashMap HashSet
LinkedListMultimap * LinkedHashMap``* LinkedList``*
LinkedHashMultimap** LinkedHashMap LinkedHashSet
TreeMultimap TreeMap TreeSet
ImmutableListMultimap ImmutableMap ImmutableList
ImmutableSetMultimap ImmutableMap ImmutableSet

4、除了不可变的实现之外,每个实现都支持空键和值。并不是所有的实现都是作为一个Map<K,Collection<V>>实现的(特别是一些Multimap实现使用自定义哈希表来最小化开销。)

在线演示源码:https://gitee.com/wangmx1993/apache-study/blob/master/src/main/java/com/wmx/guava/MultimapTest.java

BiMap 双向映射

1、将值映射回键的传统方法是维护两个独立的映射,并使它们保持同步,但这很容易产生错误,并且当映射中已经存在一个值时,可能会非常混乱。例如:

Map<String, Integer> nameToId = Maps.newHashMap();
Map<Integer, String> idToName = Maps.newHashMap();

nameToId.put("Bob", 42);
idToName.put(42, "Bob");

2、BiMap 提供了多种实现:

键值映射实现 值键映射实现 对应BiMap
HashMap HashMap HashBiMap
ImmutableMap ImmutableMap ImmutableBiMap
EnumMap EnumMap EnumBiMap
EnumMap HashMap EnumHashBiMap

在线演示源码:https://gitee.com/wangmx1993/apache-study/blob/master/src/main/java/com/wmx/guava/BiMapTest.java

Table 表结构数据

1、当试图一次在多个键上建立索引时,您将得到类似 Map<FirstName,Map<LastName,Person>> 的代码,这很难看,而且使用起来很尴尬。Guava 提供了一个新的集合类型 Table,它支持任何“row”类型和“column”类型的这个用例。

2、Table 提供了多种实现:

HashBasedTable:基本上是由 HashMap<R,HashMap<C,V>> 支持的。

TreeBasedTable:基本上是由 TreeMap<R,TreeMap<C,V>> 支撑的。

ImmutableTable

ArrayTable:要求在构造时指定行和列的完整范围,但在表密集时由二维数组支持以提高速度和内存效率,ArrayTable的工作原理与其他实现有些不同

在线演示源码:https://gitee.com/wangmx1993/apache-study/blob/master/src/main/java/com/wmx/guava/TableTest.java

ClassToInstanceMap 类型映射到实例

1、有时 key 并不是单一的类型,而是多种类型,Guava 为此提供了 ClassToInstanceMap,key 可以是多种类型,value 是此类型的实例。

2、ClassToInstanceMap 的实现有: MutableClassToInstanceMap 和 ImmutableClassToInstanceMap 的实现。

在线演示源码:https://gitee.com/wangmx1993/apache-study/blob/master/src/main/java/com/wmx/guava/ClassToInstanceMapTest.java

JDK 集合辅助工具类

1、任何有 JDK 集合框架经验的程序员都知道并喜欢其中提供的实用程序 java.util.Collections,Guava 提供了许多适用于集合的静态方法实用程序。

接口 属于 JDK 还是 Guava 对应 Guava API
Collection JDK Collections2
List JDK Lists
Set JDK Sets
SortedSet JDK Sets
Map JDK Maps
SortedMap JDK Maps
Queue JDK Queues
Multiset Guava Multisets
Multimap Guava Multimaps
BiMap Guava Maps
Table Guava Tables

Lists 在线演示:https://gitee.com/wangmx1993/apache-study/blob/master/src/main/java/com/wmx/guava/ListsTest.java

Sets 在线演示:https://gitee.com/wangmx1993/apache-study/blob/master/src/main/java/com/wmx/guava/SetsTest.java

JDK 基本类型辅助工具类

1、Guava 为 Java JDK 的基本类型提供了实用程序类:

基本类型 Guava 辅助工具类
byte Bytes, SignedBytes, UnsignedBytes
short Shorts
int Ints, UnsignedInteger, UnsignedInts
long Longs, UnsignedLong, UnsignedLongs
float Floats
double Doubles
char Chars
boolean Booleans

Ints 在线演示源码:https://gitee.com/wangmx1993/apache-study/blob/master/src/main/java/com/wmx/guava/IntsTest.java

doubles 在线演示源码:https://gitee.com/wangmx1993/apache-study/blob/master/src/main/java/com/wmx/guava/DoublesTest.java

booleans 在线演示源码:https://gitee.com/wangmx1993/apache-study/blob/master/src/main/java/com/wmx/guava/BooleansTest.java

其它类型同理。

JDK 字符串辅助工具类

1、Strings 类中提供了少数几个常用的符串实用程序。在线演示源码。

2、Joiner 是连接器,用于连接 java.lang.Iterable、java.util.Iterator、java.lang.Object[] 中的元素。在线演示源码。

3、Splitter 是分割器,用于分割字符序列 java.lang.CharSequence,在线演示源码。

4、CharMatcher 字符匹配器,用于匹配字符,可以将 CharMatcher 视为代表一类特定的字符,如数字或空白。注意:CharMatcher 只处理 char 值。在线演示源码。

Stopwatch 秒表

1、google 的秒表 Stopwatch 相比 Spring framewrk core 包 和 apache commons lang3 包的秒表是最方便使用的。

2、此类不是线程安全的。

   /**
     * Stopwatch createStarted():创建(并启动)一个新的秒表,使用 System#nanoTime 来作为其时间源。
     * Stopwatch createUnstarted():创建(但不启动)一个新的秒表,使用 System#nanoTime 来作为其时间源。
     * long elapsed(TimeUnit desiredUnit):返回此秒表上显示的当前已用时间,以所需的时间单位表示,任何分数向下舍入
     * boolean isRunning():如果已在此秒表上调用start()},并且自上次调用start()以来未调用stop(),则返回true
     * Stopwatch reset():将此秒表的运行时间设置为零,并将其置于停止状态。
     * Stopwatch start():启动秒表,如果秒表已经在运行,则 IllegalStateException
     * Stopwatch stop():停止秒表,将来的读取将返回到目前为止经过的固定持续时间。
     * tring toString():返回当前运行时间的字符串表示形式,比如 2.588 s,106.8 ms
     */
    @Test
    public void testStopwatch() throws InterruptedException {
        SecureRandom secureRandom = new SecureRandom();
        Stopwatch stopwatch = Stopwatch.createStarted();

        int nextInt = secureRandom.nextInt(2000);
        System.out.println("任务1预算耗时:" + nextInt);//任务1预算耗时:81
        TimeUnit.MILLISECONDS.sleep(nextInt);
        System.out.println("\t任务1实际耗时:" + stopwatch.elapsed(TimeUnit.MILLISECONDS) + "(毫秒)");//	任务1实际耗时:563(毫秒)

        stopwatch.reset().start();
        nextInt = secureRandom.nextInt(4000);
        System.out.println("任务2预算耗时:" + nextInt);//任务2预算耗时:1591
        TimeUnit.MILLISECONDS.sleep(nextInt);
        System.out.println("\t任务2实际耗时:" + stopwatch.toString());//	任务2实际耗时:1.592 s

        stopwatch.reset().start();
        nextInt = secureRandom.nextInt(3000);
        System.out.println("任务3预计耗时:" + nextInt);//任务3预计耗时:1964
        TimeUnit.MILLISECONDS.sleep(nextInt);
        System.out.println("\t任务3实际耗时:" + stopwatch.stop().toString());//	任务3实际耗时:1.965 s
    }

src/main/java/com/wmx/guava/StopwatchTest.java · 汪少棠/apache-study – Gitee.com

RateLimiter 限速器/限流器

1、com.google.common.util.concurrent.RateLimiter 限速器对于并发使用是安全的,它将限制来自所有线程的调用的总速率。

2、限速器通常用于限制访问某些物理或逻辑资源的速率,比如限制某个接口或者方法的请求速率 一秒内不超过10次。JDK 原生的 java.util.concurrent.Semaphore 是限制并发访问的数量而不是速率。

static RateLimiter create(double permitsPerSecond)

1、创建一个具有指定稳定吞吐量的 RateLimiter,permitsPerSecond 为“每秒许可数”(通常称为QPS)。确保在任何给定的一秒内平均发出不超过permitsPerSecond个的请求。

2、permitsPerSecond 不能为0或者负数,否则报错。

static RateLimiter create(double permitsPerSecond, Duration warmupPeriod) warmupPeriod 表示预热期。在此期间 RateLimiter 平稳地提高其速率,直到该时段结束时达到最大速率(只要有足够的请求使其饱和)。类似地,如果 RateLimiter 在 warmupPeriod 的持续时间内保持未使用,它将逐渐恢复到“冷”状态,即它将经历与首次创建时相同的预热过程。
double getRate() 返回此RateLimiter的稳定速率(根据xxx/秒允许的速率)
setRate(double permitsPerSecond)

1、更新此{@code RateLimiter}的稳定速率,即在构造{@code-RateLimiter}的工厂方法中提供的{@code-permitsPerSecond}参数。由于此调用,当前受限制的线程将不会被唤醒,因此它们不会观察到新的速率;只有随后的请求才会。

2、permitsPerSecond 不能为0或者负数,否则报错。

boolean tryAcquire()

获取许可证,不做任何等待,如果获得了许可证,则返回true,否则返回 false。

此方法等效于 tryAcquire(1)。

boolean tryAcquire(Duration timeout)

获取许可证,并最长等待 timeout 时间,如果超时还未获取,则返回 false。

此方法等效于 tryAcquire(1,timeout)。

boolean tryAcquire(int permits)

permissions 表示获取的许可数量,不要为0或者负数。

立即获取,不会等待,获取到了返回 true,否则返回false。

boolean tryAcquire(int permits, Duration timeout)  timeout 等待许可证获取的最长时间。负值被视为零。

double acquire()

double acquire(int permits)

获取一个许可证,一直阻塞等待,直到获取。

1、permissions 获取的许可数量,不能为0或者负数。

2、返回等待的时间,以秒为单位。

// 示例1:假设有一个要执行的任务列表,希望每秒提交不能超过2个

 final RateLimiter rateLimiter = RateLimiter.create(2.0);
 void submitTasks(List tasks, Executor executor) {
   for (Runnable task : tasks) {
     rateLimiter.acquire(); // may wait
     executor.execute(task);
   }
 }

// 示例2:假设产生一个数据流,希望将其限制在每秒5kb,这可以通过要求每个字节有一个许可证,并指定每秒5000个许可证的速率来实现

final RateLimiter rateLimiter = RateLimiter.create(5000.0);
 void submitPacket(byte[] packet) {
   rateLimiter.acquire(packet.length);
   networkService.send(packet);
 }

src/main/java/com/wmx/guava/RateLimiterTest.java · 汪少棠/apache-study – Gitee.com。

ListenableFuture 异步线程侦听器

1、Guava的ListenableFuture顾名思义就是可以监听的Future,是对java原生Future的扩展增强。

2、原生 Future表示一个异步计算任务,当任务完成时可以得到计算结果。如果希望一旦计算完成就拿到结果展示给用户或者做另外的计算,就必须使用另一个线程不断的查询计算状态。这样做,代码复杂,而且效率低下。使用「Guava ListenableFuture」可以帮检测Future是否完成,不需要再通过get()方法等待异步的计算结果,如果完成就自动调用回调函数,这样可以减少并发程序的复杂度。

3、ListenableFuture是一个接口,它从jdk的Future接口继承,添加了void addListener(Runnable listener, Executor executor)方法。

public class ListenableFutureTest {

    private static final Logger log = LoggerFactory.getLogger(ListenableFutureTest.class);

    @Test
    public void listenableFutureTest1() throws InterruptedException {
        // 原生线程池
        ExecutorService executorService = Executors.newCachedThreadPool();
        // 通过MoreExecutors类的静态方法listeningDecorator方法初始化一个ListeningExecutorService实例(侦听执行程序服务)
        ListeningExecutorService listeningExecutorService = MoreExecutors.listeningDecorator(executorService);
        // ListeningExecutorService实例的submit方法即可初始化ListenableFuture对象(委托执行器,用于将来监听执行结果)。
        final ListenableFuture<Integer> listenableFuture = listeningExecutorService.submit(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                int result = 200;
                int randomInt = RandomUtil.randomInt(500, 3000);
                log.info("支线任务开始,预计执行{}毫秒.", randomInt);
                TimeUnit.MILLISECONDS.sleep(randomInt);
                log.info("支线任务完成,准备返回结果{}", result);
                // System.out.println(1 / 0);
                return result;
            }
        });

        // 添加回调方法监听异步执行的结果(如果没有监听,则子线程发生异常后并不会打印异常信息)
        Futures.addCallback(listenableFuture, new FutureCallback<Integer>() {

            // 子线程异步执行成功结束后触发
            @Override
            public void onSuccess(@Nullable Integer result) {
                log.info("支线任务执行完成,返回结果:" + result);
            }

            // 子线程异步执行异常后触发
            @Override
            public void onFailure(Throwable t) {
                log.info("支线任务执行失败:" + ExceptionUtils.getStackTrace(t));
            }
        }, listeningExecutorService);

        log.info("主线任务开始延迟5秒");
        TimeUnit.MILLISECONDS.sleep(5000);
        log.info("主线任务结束");
        // 2023-05-28 10:50:57.696 ==> [main] ==> INFO  com.wmx.guava.ListenableFutureTest - 主线任务开始延迟5秒
        // 2023-05-28 10:50:57.710 ==> [pool-1-thread-1] ==> INFO  com.wmx.guava.ListenableFutureTest - 支线任务开始,预计执行2741毫秒.
        // 2023-05-28 10:51:00.473 ==> [pool-1-thread-1] ==> INFO  com.wmx.guava.ListenableFutureTest - 支线任务完成,准备返回结果200
        // 2023-05-28 10:51:00.477 ==> [pool-1-thread-2] ==> INFO  com.wmx.guava.ListenableFutureTest - 支线任务执行完成,返回结果:200
        // 2023-05-28 10:51:02.714 ==> [main] ==> INFO  com.wmx.guava.ListenableFutureTest - 主线任务结束
    }

}

src/main/java/com/wmx/guava/ListenableFutureTest.java · 汪少棠/apache-study – Gitee.com。

今天的文章谷歌核心库_java常用utils工具类分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/82590.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注