Java 8 Map 中新增的方法使用记录

得益于 Java 8 的 default 方法特性,Java 8 对 Map 增加了不少实用的默认方法,像 getOrDefault, forEach, replace, replaceAll, putIfAbsent, remove(key, value), computeIfPresent, computeIfAbsent, compute 和merge 方法。另外与 Map 相关的 Map.Entry 也新加了多个版本的 comparingByKey 和 comparingByValue 方法。

为达到熟练运用上述除 getOrDefault 和 forEach 外的其他方法,有必要逐一体验一番,如何调用,返回值以及调用后的效果如何。看看每个方法不至于 Java 8 那么多年还总是  if(map.containsKey(key))... 那样的老套操作。

前注:Map 新增方法对  present 的判断是 map.containsKey(key) && map.get(key) != null,简单就是  map.get(key) != null,也就是即使 key 存在,但对应的值为 null 的话也视为 absent。absent 就是 map.get(key) == null。

不同 Map 实现对 key/value 是否能为 null 有不同的约束, HashMap, LinkedHashMap, key 和 value 都可以为 null 值,TreeMap 的 key 为不能为 null, 但 value 可以为 null, 而 Hashtable, ConcurrentMap 则 key 和 value 都不同为 null。一句话 absent/present 的判断是 map.get(key) 是否为 null。

方法介绍的顺序是它们相对于本人的生疏程度而定的。每个方法介绍主要分两部分,参考实现代码与示例代码执行效果。参考实现代码摘自 JDK 官方的 Map JavaDoc

getOrDefault 方法

本想忽略这个方法的测试,因为涉及到 key 存在,值为 null 的情况。当 key 不存在或相关联的值为 null 时,返回默认值,否则返回实际值。不要认为 key 存在时总是返回 map.get(key) 的值。

参考实现:

阅读全文 >>

Spring Boot 与 Logback 日志配置

本文记录 SpringBoot 与 Logback 是如何工作的,即观察 SpringBoot 中 Logback  是怎么一步一步初始化的。用以测试的 SpringBoot 版本是 1.5.16, 而非最新的 SpringBoot 2。关于 SpringBoot 日志的官方文档在 Logging, 但不太详细或透彻。本文也不承诺说就理解得更有深度,只是为官方文档提供更多方面的参考。

SpringBoot 默认使用 Slf4J + Logback 来记录日志,对于一个基本的依赖于

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>

的 Spring Boot 项目,上面组件依赖了 spring-boot-starter-logging 组件,而该组件又引入了以下几个依赖

  1. logback-classic:   依赖了 Slf4J
  2. jcl-over-slf4j
  3. jul-to-slf4j
  4. log4j-over-slf4j

相当于把其他的日志框架全桥接到了 Slf4J + Logback 上去了。 阅读全文 >>

Amazon SQS 触发 AWS Lambda 及重试/DLQ

Amazon 在 2018 年 6 月份宣布可以设置用 SQS 来触发 Lambda,SQS 不再是单纯用于 ECS 服务中,或用于伸缩控制的。这儿就来亲自尝试一下用 SQS 驱动的 Lambda,以及要注意的要素。

首先使用 Java 编写 Lambda 的话,AWS 在 com.amazonaws:aws-lambda-java-events:2.20 版本开始加入了 com.amazonaws.services.lambda.runtime.events.SQSEvent 类,可是这个版本的 aws-lambda-java-events 是有所限的,因为 SQSEvent.SQSMessage 类是私有的,这就造成不能获取到 SQSEvent 中的记录数据。

//下面的操作代码无法编译,因为 SQSEvent.SQSMessage 是私有的,不可访问
SQSEvent.SQSMessage sqs = sqsEvent.getRecords().get(0); 
sqsEvent.getRecords().get(0).getBody();

Java 使用 SQS 来驱动 Lambda 的话,至少需要 com.amazonaws:aws-lambda-java-events:2.2.1 版本,从此 SQSEvent.SQSMessage 变成 public 了。该版本是于  2018 年 6 月传到 Maven 官方中央仓库的,这就是那时才能真正用来写 Java 的 SQS 触发的 Lambda.

同时此篇也是作为上文 AWS Lambda 重试与死信队列(DLQ) 的一个很重要的补充。在此也会验证 SQS 触发的 Lambda 的重试机制以及 DLQ 相关的内容。 阅读全文 >>