Guava学习(一)

news/2025/2/22 21:53:13/

避免使用Null值

在程序开发中,特别是涉及到集合的场景,90%都不允许null值的存在,特别是null值存在歧义,当使用ConcurrentMap是为了并发安全不允许将null值作为key,但是普通map允许null值为key,当null作为key时它与普通的key类似,多次put会覆盖,二次hash计算的桶默认为0。当null作为value时,当我们拿到一个value为null,我们无法判断是“不存在这个key”还是“这个key对应的值为null”。

使用Optional 可选在对集合进行处理解决掉空集合的情况

image-20250210153558185

//提供默认值
String result = Optional.fromNullable(getValue()).or("默认值");
​// 返回Optional而不是直接返回可能为null的对象public Optional<User> findUserById(Long id) {User user = userRepository.findById(id);return Optional.fromNullable(user);}// 方法链式调用public String getUserEmail(Long userId) {return Optional.fromNullable(findUserById(userId)).transform(User::getEmail).or("未找到邮箱");}// 条件判断和默认值处理public Address getShippingAddress(Order order) {return Optional.fromNullable(order).transform(Order::getShippingAddress).or(new Address("默认地址"));}

先决条件 Preconditions

可以作为JSR提供的参数校验替代(@Value、@NotBlank、@NotEmpty、@NotBlank)

image-20250210155140857

image-20250210155324669

结合ControllerAdvice统一异常处理进行友好的错误抛出

Objects工具类

对Object类的常见方法进行了工具类封装。

Objects.equal(a,b)

Objects.hashCode(a,b,c...)

Objects.toString(a)

Objects.compareTo(a,b)

相比于Guava提供的Objects类,我们现在更喜欢使用JDK提供的Objects类,功能几乎一样

Collections集合

Immutable Collections不可变集合

  1. 线程安全

  2. 一但创建就不能再变

  3. 由于不需要变化,它比可变集合更节省内存

  4. 可以作为常数使用

image-20250210162131383

image-20250210162305806

创建:

//of
ImmutableSet.of("a", "b", "c", "a", "d", "b");//copyOf or asList
void thingamajig(Collection<String> collection) {ImmutableList<String> defensiveCopy = ImmutableList.copyOf(collection);...
}//builder()
public static final ImmutableSet<Color> GOOGLE_COLORS =ImmutableSet.<Color>builder().addAll(WEBSAFE_COLORS).add(new Color(0, 191, 255)).build();

Multiset 多集合

一般用于计数

取代了传统的Map+for循环进行元素计数的方式。

image-20250210164717008

Multiset与Map在功能上有相似的地方,但是本质上只是Multiset实现了Map的功能,Multiset仍然是真正的Collection类型

image-20250210164933568

Multimap多地图

实现了一对多的映射(处理一个键对多个值的映射数据结构)

a -> 1
a -> 2
a -> 4
b -> 3
c -> 5

例如当我们在做图论的编程题时经常遇到对点的存储,Map<K, List<V>>Map<K, Set<V>>,使用Multimap可以取代这种结构

image-20250210165947487

// 创建 Multimap
Multimap<String, String> multimap = ArrayListMultimap.create();
​
// 添加键值对
multimap.put("fruits", "apple");
multimap.put("fruits", "banana");
multimap.put("fruits", "orange");
multimap.put("vegetables", "carrot");
multimap.put("vegetables", "potato");
​
// 获取值
Collection<String> fruits = multimap.get("fruits");
// 输出: [apple, banana, orange]
​
// 检查特定键值对是否存在
boolean hasApple = multimap.containsEntry("fruits", "apple"); // true
​
// 移除键值对
multimap.remove("fruits", "apple");
​
// 获取所有条目数
int size = multimap.size(); // 所有键值对的总数
​
// 获取不同键的数量
int keySize = multimap.keySet().size();

BiMap 一一映射

当我们既需要键映射到值又需要值映射回键时,采用BiMap取代Map<K,V>+Map<V,K>

BiMap要求键和值都是唯一的,如果试图把键映射到已存在的值上会抛出IllegalArgumentException

//BiMap<K,V>正常情况下可以当作Map<K,V>使用,但是值要求唯一//使用inverse()方法查看逆值
BiMap<String, Integer> userId = HashBiMap.create();
...
​
String userForId = userId.inverse().get(id);  

image-20250210170743951

Table表格

表格类型,取代了Map<R,Map<C,V>>

有类似于excel的行列概念

Table<Vertex, Vertex, Double> weightedGraph = HashBasedTable.create();
weightedGraph.put(v1, v2, 4);
weightedGraph.put(v1, v3, 20);
weightedGraph.put(v2, v3, 5);
​
weightedGraph.row(v1); // returns a Map mapping v2 to 4, v3 to 20
weightedGraph.column(v3); // returns a Map mapping v1 to 20, v2 to 5
​
​
​
//使用案例
// 创建 Table
Table<String, String, Integer> table = HashBasedTable.create();
​
// 添加数据
table.put("张三", "语文", 90);
table.put("张三", "数学", 95);
table.put("李四", "语文", 85);
table.put("李四", "数学", 88);
​
// 获取特定值
Integer score = table.get("张三", "语文"); // 90
​
// 检查是否包含特定单元格
boolean hasScore = table.contains("张三", "语文"); // true
​
// 删除数据
table.remove("张三", "语文");
​
// 获取表格大小
int size = table.size(); // 所有单元格的数量

Caches 缓存

缓存: 利用空间换时间的思想,将一些较为常见的查询数据进行本地保存,优化查询速度,减轻mysql与redis等存储的压力。

如果你在项目中想使用到本地缓存,一种方式是使用线程安全的ConcurrentHashMap,但是使用Cache可以实现ConcurrentHashMap的所有功能,还提供了缓存所需要的内存限制、时间限制、淘汰策略、移除监听等

搭配Spring完整使用例子:

@Configuration
@EnableCaching
public class GuavaCacheConfig {
​@Value("${cache.user.maximum-size:1000}")private long maximumSize;
​@Value("${cache.user.expire-after-write:30}")private long expireAfterWrite;
​@Value("${cache.user.expire-after-access:15}")private long expireAfterAccess;
​@Beanpublic Cache<String, User> userCache() {CacheBuilder<Object, Object> cacheBuilder = CacheBuilder.newBuilder()// 基本配置.maximumSize(maximumSize)                          // 最大缓存条目数.expireAfterWrite(expireAfterWrite, TimeUnit.MINUTES)    // 写入后过期时间.expireAfterAccess(expireAfterAccess, TimeUnit.MINUTES) // 访问后过期时间// 高级配置.concurrencyLevel(4)                // 并发级别.initialCapacity(100)              // 初始容量.softValues()                      // 使用软引用存储值// 统计和监控.recordStats()                     // 开启统计.removalListener(notification -> {log.info("Cache removal - Key: {}, Value: {}, Cause: {}", notification.getKey(),notification.getValue(),notification.getCause());});
​return cacheBuilder.build();}
​// 用于监控的 Metrics@Beanpublic CacheMetricsManager cacheMetricsManager(Cache<String, User> userCache) {return new CacheMetricsManager(userCache);}
}
​
@Component
@Slf4j
class CacheMetricsManager {private final Cache<String, User> cache;
​public CacheMetricsManager(Cache<String, User> cache) {this.cache = cache;}
​@Scheduled(fixedRate = 300000) // 每5分钟执行一次public void logCacheMetrics() {CacheStats stats = cache.stats();log.info("Cache Stats - Hits: {}, Misses: {}, Hit Rate: {}", stats.hitCount(),stats.missCount(),stats.hitRate());}
}


http://www.ppmy.cn/news/1572595.html

相关文章

springboot整合mybatis-plus(保姆教学) 及搭建项目

一、Spring整合MyBatis (1)将MyBatis的DataSource交给Spring IoC容器创建并管理&#xff0c;使用第三方数据库连接池(Druid&#xff0c;C3P0等)代替MyBatis内置的数据库连接池 (2)将MyBatis的SqlSessionFactory交给Spring IoC容器创建并管理&#xff0c;使用spring-mybatis整…

MySQL8.0 高级SQL优化深度实践指南

MySQL 8.0作为当前主流的关系型数据库版本,不仅在性能上实现了显著提升,更在查询优化器和执行计划方面进行了革命性改进。新版引入了基于代价的优化器(Cost-Based Optimizer, CBO)增强功能,能够更准确地评估查询成本,并选择最优的执行路径。这种改进使得复杂查询的处理效…

20250214 随笔 Nginx 负载均衡在数据库中的应用

Nginx 负载均衡在数据库中的应用 在高并发环境下&#xff0c;数据库的性能往往是系统的瓶颈。为了提高数据库的吞吐能力、优化请求分配、减少单点故障&#xff0c;我们可以使用 Nginx 负载均衡 来优化数据库的访问。本文将介绍如何使用 Nginx 进行数据库负载均衡&#xff0c;以…

ArrayList、LinkedList、Vector

ArrayList 和 LinkedList 的区别是什么&#xff1f; 数据结构实现&#xff1a;ArrayList 是动态数组的数据结构实现&#xff0c;而 LinkedList 是双向链表的数据结构实 现。 随机访问效率&#xff1a;ArrayList 比 LinkedList 在随机访问的时候效率要高&#xff0c;因为 Linked…

moveable 一个可实现前端海报编辑器的 js 库

目录 缘由-胡扯本文实验环境通用流程1.基础移动1.1 基础代码1.1.1 data-* 解释 1.2 操作元素创建1.3 css 修饰1.4 cdn 引入1.5 js 实现元素可移动1.6 图片拖拽2.缩放3.旋转4.裁剪 懒得改文案了&#xff0c;海报编辑器换方案了&#xff0c;如果后面用别的再更。 缘由-胡扯 导火…

Include多表查询

DeepSeek 在 C# 中,Include 方法通常用于 Entity Framework (EF) 或 Entity Framework Core 中,用于 预先加载相关数据(Eager Loading)。它的主要作用是在查询数据库时,将关联的实体数据一并加载到内存中,避免后续使用时触发额外的数据库查询(即延迟加载,Lazy Loading…

conda介绍及常用命令举例

Conda 是一个开源的包管理器和环境管理工具&#xff0c;它允许用户安装、管理、运行和分析 Python 和 R 软件包及其依赖项。Conda 特别擅长于创建隔离的环境&#xff0c;以便在同一台机器上运行不同版本的软件包而不会发生冲突。 以下是一些常用的 Conda 命令及其示例&#xf…

AI如何与DevOps集成,提升软件质量效能

随着技术的不断演进&#xff0c;DevOps和AI的融合成为推动软件开发质量提升的重要力量。传统的DevOps已经为软件交付速度和可靠性打下了坚实的基础&#xff0c;而随着AI技术的加入&#xff0c;DevOps流程不仅能提升效率&#xff0c;还能在质量保障、缺陷预测、自动化测试等方面…