I customed a field annotation to annotate the field which I want to it multiplied by scale.
I'm wandering is there a better way to get annotated fields, instead of iterating over all the fields.
It's my code below:
custom annotation:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface ShowScale {
String scale();
}
Java object (the map is the matter):
class Vo {
@ShowScale(scale = "0.8")
private BigDecimal member1 = BigDecimal.ZERO;
@ShowScale(scale = "0.8")
private BigDecimal member2 = BigDecimal.ONE;
@ShowScale(scale = "0.8")
private BigDecimal member3 = BigDecimal.TEN;
private String otherMember = "leave me alone";
//this map is the matter...
private Map<String, List<InnerVo>> map;
public static class InnerVo {
@ShowScale(scale = "0.8")
private BigDecimal innerMember1 = BigDecimal.ZERO;
@ShowScale(scale = "0.8")
private BigDecimal innerMember2 = BigDecimal.ONE;
private String otherMember = "leave me alone";
@Override
public String toString() {
return new ToStringBuilder(this)
.append("innerMember1", innerMember1)
.append("innerMember2", innerMember2)
.append("otherMember", otherMember)
.toString();
}
}
public Vo() {
HashMap<String, List<InnerVo>> map = new HashMap<>();
ArrayList<InnerVo> list = new ArrayList<>();
list.add(new InnerVo());
list.add(new InnerVo());
list.add(new InnerVo());
ArrayList<InnerVo> list1 = new ArrayList<>();
list1.add(new InnerVo());
list1.add(new InnerVo());
list1.add(new InnerVo());
ArrayList<InnerVo> list2 = new ArrayList<>();
list2.add(new InnerVo());
list2.add(new InnerVo());
list2.add(new InnerVo());
map.put("key", list);
map.put("key1", list1);
map.put("key2", list2);
this.map = map;
}
@Override
public String toString() {
return new ToStringBuilder(this)
.append("member1", member1)
.append("member2", member2)
.append("member3", member3)
.append("otherMember", otherMember)
.append("map", map)
.toString();
}
}
My implement:
public class ClassTest {
public static void main(String[] args) throws Exception {
Vo vo = new Vo();
System.out.println("before----->:" + vo);
handle(vo);
System.out.println("after----->:" + vo);
}
/**
* All the fields (include in map and list) annotated by @ShowScale
* should be multiplied by scale.
*
* @param obj
*/
private static <T> void handle(T obj) {
try {
Class<?> clz = obj.getClass();
String className = clz.getName();
System.out.println("\n-------> objType:" + className);
if (className.contains("java.util.ArrayList")) {
for (Object o : (List) obj) {
handle(o);
}
} else if (className.contains("java.util.Map")) {
Map map = (Map) obj;
map.forEach((key, value) -> {
System.out.println(key + " :" + value);
handle(value);
});
} else {
for (Field f : clz.getDeclaredFields()) {
String typeName = f.getType().getTypeName();
if (f.isAnnotationPresent(ShowScale.class)) {
f.setAccessible(true);
BigDecimal o = (BigDecimal) f.get(obj);
System.out.println("o = " + o);
BigDecimal scale = new BigDecimal(f.getAnnotation(ShowScale.class).scale());
f.set(obj, o.multiply(scale).setScale(2, RoundingMode.HALF_UP));
} else if (typeName.contains(Map.class.getName())) {
f.setAccessible(true);
Map map = (Map) f.get(obj);
map.forEach((key, value) -> {
System.out.println(key + " :" + value);
handle(value);
});
} else if (typeName.contains(List.class.getName())) {
f.setAccessible(true);
for (Object o : (List) f.get(obj)) {
handle(o);
}
}
}
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
thank you for any tips :)
Aucun commentaire:
Enregistrer un commentaire