代码优化001-不要增加不必要的查询
今天在写一个功能,把类对应属性的值又0变为null
第一阶段
由于没有集体需求,只是一个工具类的实现,所以完成的比较简单
/**
* @author luohuiqi
* @Description:
* @Date: 2019/7/1 13:07
*/
@Getter
@AllArgsConstructor
public enum AttributeCovertsEnum {
ZEROTONULL{
@Override
public <E> E apply(E e, String field) {
try {
Field field_name = e.getClass().getDeclaredField(field);
field_name.setAccessible(true);
boolean b = "java.lang.Integer".equals(field.getType().getName()) && (field.get(e) != null && 0 == (int) field.get(e));
if (b) {
field_name.set(e, null);
}
return e;
} catch (Exception e1) {
e1.printStackTrace();
}
return e;
}
};
public abstract <E> E apply(E e, String field);
}
第二阶段
代码应该是满足功能的,但是,具体的业务场景是,把具体的类里所有为0的字段都修改为null,所有,就相想到把方法的第二个参数转化为LIst<属性>,所以首先想到得到LIst<属性>。故又增加了一个方法
public static <E> List<String> getZeroFiledListV2(E e) {
Field[] fields = e.getClass().getDeclaredFields();
return Arrays.stream(fields).filter(field -> {
try {
//打开私有访问
field.setAccessible(true);
return "java.lang.Integer".equals(field.getType().getName()) && (field.get(e) !=null && 0 == (int)field.get(e));
} catch (IllegalAccessException e1) {
return false;
}
}).map(Field::getName).collect(Collectors.toList());
}
以及
@Getter
@AllArgsConstructor
public enum AttributeCovertsEnum {
ZEROTONULL{
@Override
public <E> E apply(E e, List<String> fields) {
Arrays.stream(e.get).filter(field -> {
try {
//打开私有访问
field.setAccessible(true);
return "java.lang.Integer".equals(field.getType().getName()) && (field.get(e) !=null && 0 == (int)field.get(e));
} catch (IllegalAccessException e1) {
return false;
}
}).map(Field::getName).collect(Collectors.toList())
fields.forEach(f ->{
try {
Field field_name = e.getClass().getDeclaredField(f);
field_name.setAccessible(true);
if (0 == (int)field_name.get(e)) {
field_name.set(e, null);
} else {
throw new RuntimeException("所传属性的值有误");
}
} catch (Exception e1) {
e1.printStackTrace();
}
});
return e;
}
};
public abstract <E> E apply(E e, List<String> fields);
}
第三阶段
本来就是对一个实体里的为0的属性做操作,故可以直接使用一个方法的,最后愚蠢的写写未下面的代码
/**
* @author luohuiqi
* @Description:
* @Date: 2019/7/1 13:07
*/
@Getter
@AllArgsConstructor
public enum AttributeCovertsEnum {
ZEROTONULL{
@Override
public <E> E apply(E e) {
List<String> fields = Arrays.stream(e.getClass().getDeclaredFields()).filter(field -> {
try {
//打开私有访问
field.setAccessible(true);
return "java.lang.Integer".equals(field.getType().getName()) && (field.get(e) != null && 0 == (int) field.get(e));
} catch (IllegalAccessException e1) {
return false;
}
}).map(Field::getName).collect(Collectors.toList());
fields.forEach(f ->{
try {
Field field_name = e.getClass().getDeclaredField(f);
field_name.setAccessible(true);
if (0 == (int)field_name.get(e)) {
field_name.set(e, null);
} else {
throw new RuntimeException("所传属性的值有误");
}
} catch (Exception e1) {
e1.printStackTrace();
}
});
return e;
}
};
public abstract <E> E apply(E e);
}
第四阶段
由于filter已经是过滤掉的数据,所以在foreach里面再做过滤就是多余了,所以最终可以修改为filter过滤+foreach遍历修改
/**
* @author luohuiqi
* @Description:
* @Date: 2019/7/1 13:07
*/
@Getter
@AllArgsConstructor
public enum AttributeCovertsEnum {
ZEROTONULL{
@Override
public <E> E apply(E e) {
Arrays.stream(e.getClass().getDeclaredFields()).filter(field -> {
try {
//打开私有访问
field.setAccessible(true);
return "java.lang.Integer".equals(field.getType().getName()) && (field.get(e) != null && 0 == (int) field.get(e));
} catch (IllegalAccessException e1) {
return false;
}
}).forEach(f ->{
try {
f.set(e, null);
} catch (IllegalAccessException e1) {
e1.printStackTrace();
}
});
return e;
}
};
public abstract <E> E apply(E e);
}
第五阶段
代码看来已经优化的差不多了,但是有很多不必要的try—catch代码,其实这不是最重要的,重要的是filter的复杂度是O(n),foreach的复杂度是O(n);所以整个语句的复杂度是O(n^2),下面是降低复杂度的一种实现
/**
* @author luohuiqi
* @Description:
* @Date: 2019/7/1 13:07
*/
@Getter
@AllArgsConstructor
public enum AttributeCovertsEnum {
ZEROTONULL {
@Override
public <E> E apply(E e) {
Arrays.stream(e.getClass().getDeclaredFields()).forEach(field -> {
try {
//打开私有访问
field.setAccessible(true);
boolean b = "java.lang.Integer".equals(field.getType().getName()) && (field.get(e) != null && 0 == (int) field.get(e));
if (b) {
field.set(e, null);
}
} catch (IllegalAccessException e1) {
e1.printStackTrace();
}
});
return e;
}
};
public abstract <E> E apply(E e);
}
下面的算法的复杂度是O(n)
总结
- 尽量少使用filter -foreach 式的代码
- 在写一个小功能时应该有大局观
- 完成功能实现只是一小步,应该进可能的思考优化方法以及最佳实践