gpt4 book ai didi

java - 如何使用反射来抽象(减少)代码以获取字段(Integer,Long,Float,Double)并进行一些计算?

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:05:25 26 4
gpt4 key购买 nike

我写了一个一般计算QoQ的方法。
我的想法是迭代所有字段并计算它是 long 、 integer 、 float 还是 double 并将字段名称和结果设置为映射。
写这段代码很容易,但我发现它太丑了:

    public static <T> Map<String, String> calculateQoq(final T now, final T before) {
final Field[] declaredFields = now.getClass().getDeclaredFields();
if (ArrayUtils.isEmpty(declaredFields)) {
return Collections.emptyMap();
}
final Map<String, String> map = new HashMap<>(declaredFields.length, 1);
for (final Field f : now.getClass().getDeclaredFields()) {
try {
f.setAccessible(true);
final Object a = f.get(before);
if (a instanceof Integer) {
final Integer beforeNum = (Integer)a;
if (beforeNum == null || beforeNum == 0) {
map.put(f.getName(), ZERO);
continue;
}
final Integer nowNum = (Integer) f.get(now);
if (nowNum == null) {
map.put(f.getName(), ZERO);
continue;
}
map.put(f.getName(), formatTwoFraction((nowNum - beforeNum) * 1.0 / beforeNum));
} else if (a instanceof Long) {
final Long beforeNum = (Long)a;
if (beforeNum == null || beforeNum == 0) {
map.put(f.getName(), ZERO);
continue;
}
final Long nowNum = (Long) f.get(now);
if (nowNum == null) {
map.put(f.getName(), ZERO);
continue;
}
map.put(f.getName(), formatTwoFraction((nowNum - beforeNum) * 1.0 / beforeNum));
} else if (a instanceof Double) {
final Double beforeNum = (Double)a;
if (beforeNum == null || beforeNum == 0) {
map.put(f.getName(), ZERO);
continue;
}
final Double nowNum = (Double) f.get(now);
if (nowNum == null) {
map.put(f.getName(), ZERO);
continue;
}
map.put(f.getName(), formatTwoFraction((nowNum - beforeNum) / beforeNum));
} else if (a instanceof Float) {
final Float beforeNum = (Float)a;
if (beforeNum == null || beforeNum == 0) {
map.put(f.getName(), ZERO);
continue;
}
final Float nowNum = (Float) f.get(now);
if (nowNum == null) {
map.put(f.getName(), ZERO);
continue;
}
map.put(f.getName(), formatTwoFraction((nowNum - beforeNum) / beforeNum));
}
} catch (final Exception e) {
LOG.error("calculateQoq - get field failed - " + f.getName(), e);
}
}
return map;
}

我只是重复几乎相同的逻辑四次,我尝试使用类似 <T extends Number> void doXXX(T before, T now) 的东西
但是Number无法计算。
而 Integer、Long 和其他没有像 NumberEquals 这样的通用接口(interface)。 (equals 的默认实现进行类型检查)或 Divideable ...
java中也没有宏...
我尝试了几次 emmmm 但还没有解决方案。

所以我想知道有什么方法可以做抽象并减少这个逻辑。

最佳答案

我建议将问题隔离到一个单独的转换方法中,该方法将 Number 作为参数并返回一个可以统一处理的原始类型。例如:

private static int toInt(Number number) {
// domain-specific conversion logic
}

然后可以简化代码以避免通过单个案例切换到确切的类型:

if(a instanceof Number) {
int beforeNum = toInt((Number)a);
if(beforeNum == 0) {
map.put(f.getName(), ZERO);
continue;
}
// and so on

问题的症结在于如何详细完成转换将是特定于域的(即,将取决于如何解释数字)。假设数字代表货币,那么乘以 100(或使用任何小数单位)并使用整数运算可能更安全。在任何情况下,此代码都可以利用 Number 上的 intValue()(或其他类似的)方法再次避免切换。例如:

private static int toInt(Number number) {
if( number == null ) {
return 0;
}
return ((int) (number.doubleValue() * 100.0)); // Example only
}

关于java - 如何使用反射来抽象(减少)代码以获取字段(Integer,Long,Float,Double)并进行一些计算?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57823962/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com