Apache Commons Collections 是一个扩展了 Java 标准库里的 Collection 结构的第三方基础库,它提供了很多强有力的数据结构类型并实现了各种集合工具类。作为 Apache 开源项目的重要组件,被广泛运用于各种 Java 应用的开发。
目录
JAVA环境
java version "1.8.0_66"
Java(TM) SE Runtime Environment (build 1.8.0_66-b18)
Java HotSpot(TM) 64-Bit Server VM (build 25.66-b18, mixed mode)
Apache Commons Collections 依赖版本:Commons Collection 3.2.1
依赖版本
- commons-collections : 3.1 - 3.2.1
- TransformedMap - jdk < 8u71
检查依赖配置
确认项目中是否正确引入了 Apache Commons Collections 的依赖。如果使用的是 Maven,可以在 pom.xml
文件中添加以下依赖:
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
资源下载
前置知识
AbstractMapDecorator
首先 CC 库中提供了一个抽象类org.apache.commons.collections.map.AbstractMapDecorator
,这个类是 Map 的扩展,并且从名字中可以知道,这是一个基础的装饰器,用来给 map 提供附加功能
被装饰的 map 存在于该类的属性中,并且将所有的操作都转发给这个 map
这个类有很多实现类,各个类触发的方式不同,重点关注:
TransformedMap
LazyMap
TransformedMap
org.apache.commons.collections.map.TransformedMap
类可以在一个元素被加入到集合内时
- 自动对该元素进行特定的修饰变换
- 具体的变换逻辑由
Transformer
来定义 Transformer
在TransformedMap
实例化时作为参数传入
接下来看一下几个重点方法
decorate
TransformedMap 通过 decorate
函数将自定义的转换逻辑Transformer
装饰到传入的map
中,Transformer
分为keyTransformer
与valueTransformer
,分别对应key和value的转换逻辑
public static Map decorate(Map map, Transformer keyTransformer, Transformer valueTransformer) {
return new TransformedMap(map, keyTransformer, valueTransformer);
}
protected TransformedMap(Map map, Transformer keyTransformer, Transformer valueTransformer) {
super(map);
this.keyTransformer = keyTransformer;
this.valueTransformer = valueTransformer;
}
transformKey/transformValue
在transformKey
/transformValue
方法中,会调用keyTransformer
/valueTransformer
的transform
方法,实际进行转换
protected Object transformKey(Object object) {
if (keyTransformer == null) {
return object;
}
return keyTransformer.transform(object);
}
protected Object transformValue(Object object) {
if (valueTransformer == null) {
return object;
}
return valueTransformer.transform(object);
}
put
调用 TransformedMap
的 put
方法时,会触发transformKey
/transformValue
方法,从而触发transform
方法,实际进行转换
public Object put(Object key, Object value) {
key = transformKey(key);
value = transformValue(value);
return getMap().put(key, value);
}
当 TransformedMap 内的 key 或者 value 发生变化时,就会触发相应参数的 Transformer
的 transform
方法,这里以put
方法举例
使用实例
public static void main(String[] args) throws Exception {
// 创建基础HashMap对象
HashMap<Object, Object> map = new HashMap<>();
map.put(1, "a");
System.out.println("初始化map: " + map);
// 创建一个Transformer对象,将输入的key转换为key + 1
Transformer keyTransformer = input -> (Object) ((int) input + 1);
// 创建一个Transformer对象,将输入的value转换为value + "1"
Transformer valueTransformer = input -> input + "1";
// 使用TransformedMap包装原始map对象
Map transformedMap = TransformedMap.decorate(map, keyTransformer, valueTransformer);
// 使用put触发transform()方法
transformedMap.put(2, "b");
System.out.println("transformedMap1: " + transformedMap);
transformedMap.put(1, "c");
System.out.println("transformedMap2: " + transformedMap);
transformedMap.remove(1);
System.out.println("transformedMap3: " + transformedMap);
}
LazyMap
org.apache.commons.collections.map.LazyMap
与 TransformedMap
类似,差异在于
- 调用
get()
方法时如果传入的 key 不存在,则会触发相应参数的Transformer
的transform()
方法。
org.apache.commons.collections.map.DefaultedMap
与 LazyMap
具有相同功能,同样是 get()
方法会触发 transform()
方法
decorate
LazyMap 通过 decorate
函数将自定义的转换逻辑Transformer
装饰到传入的map
中,Transformer
只有factory
,不分keyTransformer
与valueTransformer
public static Map decorate(Map map, Transformer factory) {
return new LazyMap(map, factory);
}
protected LazyMap(Map map, Transformer factory) {
super(map);
if (factory == null) {
throw new IllegalArgumentException("Factory must not be null");
}
this.factory = factory;
}
get
调用 LazyMap 的 get
方法时,如果装饰的 map 中不存在传入的key,会触发factory
的transform
方法,实际进行转换
public Object get(Object key) {
// create value for key if key is not currently in the map
if (map.containsKey(key) == false) {
Object value = factory.transform(key);
map.put(key, value);
return value;
}
return map.get(key);
}
使用实例
public void test() {
// 创建基础HashMap对象
HashMap<Object, Object> map = new HashMap<>();
map.put(1, "a");
System.out.println("初始化map: " + map);
// 创建一个Transformer对象,将输入的key转换为key + 1
Transformer factory = input -> (Object) ((int) input + 1);
// 使用TransformedMap包装原始map对象
Map lazyMap = LazyMap.decorate(map, factory);
System.out.println("LazyMap: " + lazyMap);
System.out.println("LazyM