Java核心技术之核心类的使用(Spring Guava String JDK工具包)

简介: Google开源Java工具库Guava+Apache Commons的核心类剖析

image.png

前言:📫 作者简介:小明java问道之路,专注于研究计算机底层,就职于金融公司后端高级工程师,擅长交易领域的高安全/可用/并发/性能的设计和架构📫

🏆 Java领域优质创作者、阿里云专家博主、华为云享专家🏆

🔥 如果此文还不错的话,还请👍关注点赞收藏三连支持👍一下博主哦

本文导读

Google开源Java工具库Guava+Apache Commons的核心类剖析


一、Guava包的核心类剖析

Guava工具包提供了一堆工具类,在实际的开发中能大大简化开发效率并且保证质量。

image.png

二、常用的工具类

Cache LRU缓存

public static void cacheTest() {
    Cache<Integer, String> cache = CacheBuilder.newBuilder().maximumSize(2).build();
    cache.put(1, "first");
    cache.put(2, "second");
    cache.put(3, "third");
    String cacheValue = cache.getIfPresent(1);
    System.out.println(cacheValue);    // null
    System.out.println(cache.asMap()); // {3=third, 2=second}
}


Cache<K,V>  是缓存的顶层接口,定义了 put (新增)、 getIfPresent (查询)、 invalidate (删除)等方法定义Cache 通过建造者模式来创建, CacheBuilder 自身有两种创建方式, newBuilder() 、 from(CacheBuilderSpec)等

package com.google.common.cache;
import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.ImmutableMap;
import com.google.common.util.concurrent.ExecutionError;
import com.google.common.util.concurrent.UncheckedExecutionException;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException;
import javax.annotation.Nullable;
/**
 * A semi-persistent mapping from keys to values. Cache entries are manually added using
 * {@link #get(Object, Callable)} or {@link #put(Object, Object)}, and are stored in the cache until
 * either evicted or manually invalidated. The common way to build instances is using
 * {@link CacheBuilder}.
 *
 * <p>Implementations of this interface are expected to be thread-safe, and can be safely accessed
 * by multiple concurrent threads.
 *
 * @author Charles Fry
 * @since 10.0
 */
@GwtCompatible
public interface Cache<K, V> {
  /**
   * Returns the value associated with {@code key} in this cache, or {@code null} if there is no
   * cached value for {@code key}.
   *
   * @since 11.0
   */
  @Nullable
  V getIfPresent(Object key);
  /**
   * Returns the value associated with {@code key} in this cache, obtaining that value from {@code
   * loader} if necessary. The method improves upon the conventional "if cached, return; otherwise
   * create, cache and return" pattern. For further improvements, use {@link LoadingCache} and its
   * {@link LoadingCache#get(Object) get(K)} method instead of this one.
   *
   * <p>Among the improvements that this method and {@code LoadingCache.get(K)} both provide are:
   *
   * <ul>
   * <li>{@linkplain LoadingCache#get(Object) awaiting the result of a pending load} rather than
   *     starting a redundant one
   * <li>eliminating the error-prone caching boilerplate
   * <li>tracking load {@linkplain #stats statistics}
   * </ul>
   *
   * <p>Among the further improvements that {@code LoadingCache} can provide but this method cannot:
   *
   * <ul>
   * <li>consolidation of the loader logic to {@linkplain CacheBuilder#build(CacheLoader) a single
   *     authoritative location}
   * <li>{@linkplain LoadingCache#refresh refreshing of entries}, including {@linkplain
   *     CacheBuilder#refreshAfterWrite automated refreshing}
   * <li>{@linkplain LoadingCache#getAll bulk loading requests}, including {@linkplain
   *     CacheLoader#loadAll bulk loading implementations}
   * </ul>
   *
   * <p><b>Warning:</b> For any given key, every {@code loader} used with it should compute the same
   * value. Otherwise, a call that passes one {@code loader} may return the result of another call
   * with a differently behaving {@code loader}. For example, a call that requests a short timeout
   * for an RPC may wait for a similar call that requests a long timeout, or a call by an
   * unprivileged user may return a resource accessible only to a privileged user making a similar
   * call. To prevent this problem, create a key object that includes all values that affect the
   * result of the query. Or use {@code LoadingCache.get(K)}, which lacks the ability to refer to
   * state other than that in the key.
   *
   * <p><b>Warning:</b> as with {@link CacheLoader#load}, {@code loader} <b>must not</b> return
   * {@code null}; it may either return a non-null value or throw an exception.
   *
   * <p>No observable state associated with this cache is modified until loading completes.
   *
   * @throws ExecutionException if a checked exception was thrown while loading the value
   * @throws UncheckedExecutionException if an unchecked exception was thrown while loading the
   *     value
   * @throws ExecutionError if an error was thrown while loading the value
   *
   * @since 11.0
   */
  V get(K key, Callable<? extends V> loader) throws ExecutionException;
  /**
   * Returns a map of the values associated with {@code keys} in this cache. The returned map will
   * only contain entries which are already present in the cache.
   *
   * @since 11.0
   */
  ImmutableMap<K, V> getAllPresent(Iterable<?> keys);
  /**
   * Associates {@code value} with {@code key} in this cache. If the cache previously contained a
   * value associated with {@code key}, the old value is replaced by {@code value}.
   *
   * <p>Prefer {@link #get(Object, Callable)} when using the conventional "if cached, return;
   * otherwise create, cache and return" pattern.
   *
   * @since 11.0
   */
  void put(K key, V value);
  /**
   * Copies all of the mappings from the specified map to the cache. The effect of this call is
   * equivalent to that of calling {@code put(k, v)} on this map once for each mapping from key
   * {@code k} to value {@code v} in the specified map. The behavior of this operation is undefined
   * if the specified map is modified while the operation is in progress.
   *
   * @since 12.0
   */
  void putAll(Map<? extends K, ? extends V> m);
  /**
   * Discards any cached value for key {@code key}.
   */
  void invalidate(Object key);
  /**
   * Discards any cached values for keys {@code keys}.
   *
   * @since 11.0
   */
  void invalidateAll(Iterable<?> keys);
  /**
   * Discards all entries in the cache.
   */
  void invalidateAll();
  /**
   * Returns the approximate number of entries in this cache.
   */
  long size();
  /**
   * Returns a current snapshot of this cache's cumulative statistics, or a set of default values if
   * the cache is not recording statistics. All statistics begin at zero and never decrease over the
   * lifetime of the cache.
   *
   * <p><b>Warning:</b> this cache may not be recording statistical data. For example, a cache
   * created using {@link CacheBuilder} only does so if the {@link CacheBuilder#recordStats} method
   * was called. If statistics are not being recorded, a {@code CacheStats} instance with zero for
   * all values is returned.
   *
   */
  CacheStats stats();
  /**
   * Returns a view of the entries stored in this cache as a thread-safe map. Modifications made to
   * the map directly affect the cache.
   *
   * <p>Iterators from the returned map are at least <i>weakly consistent</i>: they are safe for
   * concurrent use, but if the cache is modified (including by eviction) after the iterator is
   * created, it is undefined which of the changes (if any) will be reflected in that iterator.
   */
  ConcurrentMap<K, V> asMap();
  /**
   * Performs any pending maintenance operations needed by the cache. Exactly which activities are
   * performed -- if any -- is implementation-dependent.
   */
  void cleanUp();
}

image.gif

CacheBuilder为什么不可变

当对象被不可信的库调用时,不可变形式是安全的;不可变对象被多个线程调用时,不存在竞态条件问题;不可变集合不需要考虑变化,因此可以节省时间和空间。

所有不可变的集合都比它们的可变形式有更好的内存利用率;不可变对象因为有固定不变,可以作为常量来安全使用。

@GwtCompatible(emulated = true)
public final class CacheBuilder<K, V> {

image.gif

相关文章
|
14天前
|
Java API 索引
Java基础—笔记—String篇
本文介绍了Java中的`String`类、包的管理和API文档的使用。包用于分类管理Java程序,同包下类无需导包,不同包需导入。使用API时,可按类名搜索、查看包、介绍、构造器和方法。方法命名能暗示其功能,注意参数和返回值。`String`创建有两种方式:双引号创建(常量池,共享)和构造器`new`(每次新建对象)。此外,列举了`String`的常用方法,如`length()`、`charAt()`、`equals()`、`substring()`等。
15 0
|
3天前
|
Java 关系型数据库 MySQL
Elasticsearch【问题记录 01】启动服务&停止服务的2类方法【及 java.nio.file.AccessDeniedException: xx/pid 问题解决】(含shell脚本文件)
【4月更文挑战第12天】Elasticsearch【问题记录 01】启动服务&停止服务的2类方法【及 java.nio.file.AccessDeniedException: xx/pid 问题解决】(含shell脚本文件)
28 3
|
1天前
|
Java Linux Shell
【Linux】bash: /home/stefan/jdk1.7.0_55/bin/java: /lib/ld-linux.so.2: bad ELF interpreter
【Linux】bash: /home/stefan/jdk1.7.0_55/bin/java: /lib/ld-linux.so.2: bad ELF interpreter
6 0
|
5天前
|
安全 Java API
第5章 Spring Security 的高级认证技术(2024 最新版)(上)
第5章 Spring Security 的高级认证技术(2024 最新版)
29 0
|
6天前
|
Java 关系型数据库 MySQL
一套java+ spring boot与vue+ mysql技术开发的UWB高精度工厂人员定位全套系统源码有应用案例
UWB (ULTRA WIDE BAND, UWB) 技术是一种无线载波通讯技术,它不采用正弦载波,而是利用纳秒级的非正弦波窄脉冲传输数据,因此其所占的频谱范围很宽。一套UWB精确定位系统,最高定位精度可达10cm,具有高精度,高动态,高容量,低功耗的应用。
一套java+ spring boot与vue+ mysql技术开发的UWB高精度工厂人员定位全套系统源码有应用案例
|
7天前
|
Java 编译器
Java Character 类
4月更文挑战第13天
|
7天前
|
负载均衡 Java 开发者
细解微服务架构实践:如何使用Spring Cloud进行Java微服务治理
【4月更文挑战第17天】Spring Cloud是Java微服务治理的首选框架,整合了Eureka(服务发现)、Ribbon(客户端负载均衡)、Hystrix(熔断器)、Zuul(API网关)和Config Server(配置中心)。通过Eureka实现服务注册与发现,Ribbon提供负载均衡,Hystrix实现熔断保护,Zuul作为API网关,Config Server集中管理配置。理解并运用Spring Cloud进行微服务治理是现代Java开发者的关键技能。
|
7天前
|
Oracle Java 关系型数据库
Java 开发者必备:JDK 版本详解与选择策略(含安装与验证)
Oracle Java SE 支持路线图显示,JDK 8(LTS)支持至2030年,非LTS版本如9-11每6个月发布且支持有限。JDK 11(LTS)支持至2032年,而JDK 17及以上版本现在提供免费商用许可。LTS版本提供长达8年的支持,每2年发布一次。Oracle JDK与OpenJDK有多个社区和公司构建版本,如Adoptium、Amazon Corretto和Azul Zulu,它们在许可证、商业支持和更新方面有所不同。个人选择JDK时,可考虑稳定性、LTS、第三方兼容性和提供商支持。
23 0
|
8天前
|
存储 Java
Java基础教程(7)-Java中的面向对象和类
【4月更文挑战第7天】Java是面向对象编程(OOP)语言,强调将事务抽象成对象。面向对象与面向过程的区别在于,前者通过对象间的交互解决问题,后者按步骤顺序执行。类是对象的模板,对象是类的实例。创建类使用`class`关键字,对象通过`new`运算符动态分配内存。方法包括构造函数和一般方法,构造函数用于对象初始化,一般方法处理逻辑。方法可以有0个或多个参数,可变参数用`类型...`定义。`this`关键字用于访问当前对象的属性。
|
8天前
|
安全 Java 数据安全/隐私保护
使用Spring Security进行Java身份验证与授权
【4月更文挑战第16天】Spring Security是Java应用的安全框架,提供认证和授权解决方案。通过添加相关依赖到`pom.xml`,然后配置`SecurityConfig`,如设置用户认证信息和URL访问规则,可以实现应用的安全保护。认证流程包括请求拦截、身份验证、响应生成和访问控制。授权则涉及访问决策管理器,如基于角色的投票。Spring Security为开发者构建安全应用提供了全面且灵活的工具,涵盖OAuth2、CSRF保护等功能。