使用場景:
這個場景是在Excel一對多,多對多模板導(dǎo)出場景下遇到的,常見的場景有財務(wù)報表,績效報表等,存在嵌套循環(huán)的情況下,我們就需要獲取對象的最大深度,以此實現(xiàn)循環(huán)插入,下面的行往下移動數(shù)據(jù)的最大寬度,直接貼代碼
1.新建DO對象
2.標記為自定義java對象
我這里使用了ExcelDTO注解做標記,也可自定義實現(xiàn)接口的方式做標記
3.獲取集合最大深度
4.測試
public class PerformanceService {
/**
* 標記是否是導(dǎo)出對象
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ExcelDTO {
}
@ExcelDTO
public static class User implements Serializable {
public User() {
}
public User(Integer age, String username) {
this.age = age;
this.username = username;
}
public User(List<User> userList, Integer age, String username) {
this.userList = userList;
this.age = age;
this.username = username;
}
public User(User user, List<User> userList, Integer age, String username) {
this.user = user;
this.userList = userList;
this.age = age;
this.username = username;
}
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
private List<User> userList = Lists.newArrayList();
public List<User> getUserList() {
return userList;
}
public void setUserList(List<User> userList) {
this.userList = userList;
}
private Integer age;
private String username;
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
private static Integer getObjectMaxSize(Collection<?> datas) throws Exception {
Integer maxSize = 0;
for (Iterator iterator = datas.iterator(); iterator.hasNext(); ) {
Object object = iterator.next();
maxSize += getMaxSize(object.getClass().getDeclaredFields(), object,new AtomicInteger(0));
}
return maxSize;
}
private static boolean isJavaClass(Class<?> clz) {
Annotation[] annotations = clz.getAnnotations();
for (Annotation annotation : annotations) {
if (annotation.annotationType().getSimpleName().equals("ExcelDTO")) return true;
}
return false;
}
private static String getMethodName(String fildeName) throws Exception {
byte[] items = fildeName.getBytes();
items[0] = (byte) ((char) items[0] - 'a' + 'A');
return new String(items);
}
private static Integer getMaxSize(Field[] declaredFields, Object obj, AtomicInteger loopNum) throws Exception {
Integer tempNum = 1;
int current=loopNum.get();
if(!loopNum.compareAndSet(current,current+1)||current>10){
throw new RuntimeException("對象子集引用超過深度");
}
for (Field field : declaredFields) {
if (!field.isAccessible()) field.setAccessible(true);
if (field.getType() == List.class && isJavaClass((Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0])) {//list類型
List listObject;
Method getListMethod = obj.getClass().getDeclaredMethod("get" + getMethodName(field.getName()));
listObject = (List) getListMethod.invoke(obj);
if (null == listObject || listObject.isEmpty()) {
continue;
}
Integer size = listObject.size();
tempNum = size;
for (int i = 0; i < size; i++) {
Object listDeclaredObj = listObject.get(i);
if (null == listDeclaredObj) {
continue;
}
tempNum -= 1;
tempNum += getMaxSize(listDeclaredObj.getClass().getDeclaredFields(), listDeclaredObj,loopNum);
}
} else if (isJavaClass(field.getType())) {//普通java類型
Object javaObj;
Method getListMethod = obj.getClass().getMethod("get" + getMethodName(field.getName()));
javaObj = getListMethod.invoke(obj);
if (null == javaObj) {
continue;
}
tempNum-=1;
tempNum += getMaxSize(field.getType().getDeclaredFields(), javaObj,loopNum);
continue;
}
}
return tempNum;
}
}
public static void main(String[] args) throws Exception {
ArrayList<User> obj = Lists.newArrayList();
User one = new User(1, "禮拜");
User two=new User(2,"ABC");
User three=new User(2,"dgf");
User fourths=new User(2,"hec");
User fourths2=new User(2,"hec");
User fourths3=new User(2,"hec");
User fourths4=new User(2,"hec");
// one.getUserList().add(two);
// one.getUserList().add(two);
one.setUser(three);
three.getUserList().add(fourths);
three.getUserList().add(fourths2);
three.getUserList().add(fourths3);
three.getUserList().add(fourths4);
obj.add(one);
System.out.println(getObjectMaxSize(obj));
// System.out.println(new AtomicInteger(1).compareAndSet(1, 2));
}