游戏开发——属性计算器辅助工具——知道大家都懒
序言
知道大家都懒,都挺忙的,于是提出给大家提供一个属性计算器功能,
在游戏中每一个场景对象都有着自己的属性,例如移动速度,攻击力,防御力,幸运值,三维等一系列属性值
属性牵涉的最多的几个问题,属性的常规值,也就是裸属性,装备的属性值,buff属性值,技能属性值等;
那也就牵涉了常规运算,赋值,相加,相乘等情况;
但是有的时候我们可能牵涉几十个属性,
1 /** 2 * 护盾效果最大值 3 */ 4 @FieldAnn(fieldNumber = 800, describe = "护盾效果最大值") 5 private transient long shield_max = 0; 6 /** 7 * 护盾效果每一次吸收固定伤害值 8 */ 9 @FieldAnn(fieldNumber = 801, describe = "护盾效果每一次吸收固定伤害值") 10 private transient long shield = 0; 11 /** 12 * 护盾效果每一次吸收伤害数值的百分比,配置是万分比 13 */ 14 @FieldAnn(fieldNumber = 802, describe = "护盾效果每一次吸收伤害数值的百分比,配置是万分比") 15 private transient long shield_pro = 0; 16 /** 17 * 血符的最大值 18 */ 19 @FieldAnn(fieldNumber = 900, describe = "血符的最大值") 20 private transient long reply_max = 0; 21 /** 22 * 固定数值恢复 23 */ 24 @FieldAnn(fieldNumber = 901, describe = "固定数值恢复") 25 private transient long reply = 0; 26 /** 27 * 按照比例恢复 28 */ 29 @FieldAnn(fieldNumber = 902, describe = "按照比例恢复") 30 private transient long reply_pro = 0; 31 /** 32 * 间隔时间触发直接恢复满 33 */ 34 @FieldAnn(fieldNumber = 903, describe = "间隔时间触发直接恢复满") 35 private transient long reply_all = 0; 36 37 /** 38 * 物理攻击_最小 39 */ 40 @FieldAnn(fieldNumber = 401, describe = "物理攻击_最小") 41 @Column(name = "q_attack_min", nullable = false, columnDefinition = "INT default 0") 42 protected int attackMin; 43 /** 44 * 物理攻击_最大 45 */ 46 @FieldAnn(fieldNumber = 401, describe = "物理攻击_最大") 47 @Column(name = "q_attack_max", nullable = false, columnDefinition = "INT default 0") 48 protected int attackMax; 49 /** 50 * 魔法攻击_最小 51 */ 52 @Column(name = "q_magic_attack_min", nullable = false, columnDefinition = "INT default 0") 53 @FieldAnn(fieldNumber = 402, describe = "魔法攻击_最小") 54 protected int magicAttackMin; 55 /** 56 * 魔法攻击_最大 57 */ 58 @Column(name = "q_magic_attack_max", nullable = false, columnDefinition = "INT default 0") 59 @FieldAnn(fieldNumber = 402, describe = "魔法攻击_最大") 60 protected int magicAttackMax; 61 /** 62 * 物理防御 63 */ 64 @Column(name = "q_defense", nullable = false, columnDefinition = "INT default 0") 65 @FieldAnn(fieldNumber = 403, describe = "物理防御") 66 protected int defence; 67 /** 68 * 魔法防御 69 */ 70 @Column(name = "q_magic_defence", nullable = false, columnDefinition = "INT default 0") 71 @FieldAnn(fieldNumber = 404, describe = "魔法防御") 72 protected int magicDefence; 73 74 /** 75 * 最大血量 76 */ 77 @Column(name = "q_max_hp", nullable = false, columnDefinition = "LONG default 0") 78 @FieldAnn(fieldNumber = 400, describe = "最大血量") 79 protected long maxHp; 80 81 /** 82 * 命中率 83 */ 84 @Column(name = "q_hit", nullable = false, columnDefinition = "INT default 0") 85 @FieldAnn(fieldNumber = 405, describe = "命中率") 86 protected int hit;
大约就像这样的情况,当然这只是其中一部分属性;
以前我们做属性的相加,相乘,只能按照一个属性一个属性去一一对应;
属性配置方式
在属性的配置方式中使用的形式,有例如mysql和hibernate的关系一对一的去解析属性,但是这个只适合场景对象的基本裸属性;
如果是装备的属性值或者技能,或者buff属性值,如果还是这么配置,蛋疼的事情就会出现;
如果在配置装备属性的时候还像裸属性一样一一对应,那么可能会分疯掉。
那么可能大家都会想到json字符串格式配置方式去实现属性数据的配置,解析出来以后就可以直接赋值,或者运算;这确实是一种方式,没问题;
但是在实际研发或上线运营过程中我们会发现字符串配置错误的行为,比如大小写,或者少字母等情况;
后来又改为数值类型的一一对应,比如200表示攻击力,201表示防御力这种形式;
这种配置方式减少了配置人员在配置属性时候出错的概率;
读取属性方式
属性的读取方式,如果是mysql和hibernate这种对应关系直接读取就好;
@Column(name = "q_attack_min", nullable = false, columnDefinition = "INT default 0") protected int attackMin;
在属性上加入注解,就可以;
但是如果是buff那种,
403_10000,404_10000
如果是这种形式的属性,我是如果读取的呢?
首先我们创建一个新的注解类
1 /** 2 * 属性注解,标注类型匹配 3 * <br> 4 * author 失足程序员<br> 5 * blog http://www.cnblogs.com/shizuchengxuyuan/<br> 6 * mail 492794628@qq.com<br> 7 * phone 13882122019<br> 8 */ 9 @Target(ElementType.FIELD) 10 @Retention(RetentionPolicy.RUNTIME) 11 public @interface FieldAnn { 12 13 /** 14 * 数值类型 15 * 16 * @return 17 */ 18 public int fieldNumber() default 0; 19 20 /** 21 * 属性描述字段 22 * 23 * @return 24 */ 25 public String describe() default ""; 26 27 /** 28 * 忽律字段 29 * 30 * @return 31 */ 32 public boolean alligator() default false; 33 }
这样我们就可以在字段上加入注解
1 /** 2 * 物理攻击_最大 3 */ 4 @FieldAnn(fieldNumber = 401, describe = "物理攻击_最大") 5 @Column(name = "q_attack_max", nullable = false, columnDefinition = "INT default 0") 6 protected int attackMax;
然我们需要将类的字段都反射解析出来静态存储
1 /** 2 * 类型的属性字段结构体 3 * <br> 4 * author 失足程序员<br> 5 * blog http://www.cnblogs.com/shizuchengxuyuan/<br> 6 * mail 492794628@qq.com<br> 7 * phone 13882122019<br> 8 */ 9 public class FieldStruc { 10 11 /** 12 * 13 */ 14 private final HashMap<String, Field> mapByName = new HashMap<>(); 15 /** 16 * 17 */ 18 private final HashMap<Integer, HashSet<Field>> mapfByNumber = new HashMap<>(); 19 20 public FieldStruc() { 21 } 22 23 public FieldStruc(Class<?> clazz) { 24 actionClass(clazz); 25 } 26 27 /** 28 * 如果 注解{@link FieldAnn alligator()} true 表示字段不参与计算忽律缓存 29 * 30 * @param clazz 31 */ 32 protected void actionClass(Class<?> clazz) { 33 Field[] declaredFields = clazz.getDeclaredFields(); 34 for (Field field : declaredFields) { 35 if (Modifier.isStatic(field.getModifiers()) 36 || Modifier.isFinal(field.getModifiers())) { 37 continue; 38 } 39 40 field.setAccessible(true); 41 42 FieldAnn annotation = field.getAnnotation(FieldAnn.class); 43 if (annotation != null) { 44 if (annotation.alligator()) { 45 /*忽律字段*/ 46 continue; 47 } 48 if (annotation.fieldNumber() > 0) { 49 if (!mapfByNumber.containsKey(annotation.fieldNumber())) { 50 mapfByNumber.put(annotation.fieldNumber(), new HashSet<>()); 51 } 52 mapfByNumber.get(annotation.fieldNumber()).add(field); 53 } 54 } 55 56 mapByName.put(field.getName(), field); 57 } 58 Class<?> superclass = clazz.getSuperclass(); 59 if (superclass != null) { 60 actionClass(superclass); 61 } 62 } 63 64 /** 65 * 字段名称 66 * 67 * @return 68 */ 69 public HashMap<String, Field> getMapByName() { 70 return mapByName; 71 } 72 73 /** 74 * 字段数值类型 key 值来源 {@link FieldAnn} 75 * 76 * @return 77 */ 78 public HashMap<Integer, HashSet<Field>> getMapfByNumber() { 79 return mapfByNumber; 80 } 81 }
如何使用
基础弄完了,我们需要知道如何使用
1 /** 2 * 3 * <br> 4 * author 失足程序员<br> 5 * blog http://www.cnblogs.com/shizuchengxuyuan/<br> 6 * mail 492794628@qq.com<br> 7 * phone 13882122019<br> 8 */ 9 public class TestField { 10 11 private static final FieldStruc FIELD_STRUC = new FieldStruc(TestField.class); 12 13 @FieldAnn(fieldNumber = 1) 14 private int i; 15 @FieldAnn(fieldNumber = 2) 16 private double d; 17 @FieldAnn(fieldNumber = 3) 18 private float f; 19 @FieldAnn(fieldNumber = 4) 20 private long l; 21 @FieldAnn(fieldNumber = 5) 22 private short s; 23 24 public int getI() { 25 return i; 26 } 27 28 public void setI(int i) { 29 this.i = i; 30 } 31 32 public double getD() { 33 return d; 34 } 35 36 public void setD(double d) { 37 this.d = d; 38 } 39 40 public float getF() { 41 return f; 42 } 43 44 public void setF(float f) { 45 this.f = f; 46 } 47 48 public long getL() { 49 return l; 50 } 51 52 public void setL(long l) { 53 this.l = l; 54 } 55 56 public short getS() { 57 return s; 58 } 59 60 public void setS(short s) { 61 this.s = s; 62 } 63 64 /** 65 * 追加属性 66 * 67 * @param fieldStr id_值,id_值,id_值,id_值,id_值 68 */ 69 public void setValue(String fieldStr) { 70 /*按照关键字切割*/ 71 String[] split = fieldStr.split(",|,"); 72 if (split != null && split.length > 0) { 73 for (String string : split) { 74 String[] split1 = string.split("_"); 75 if (split1 != null && split1.length == 2) { 76 FIELD_STRUC.setFieldValue(Integer.valueOf(split1[0]), this, split1[1]); 77 } 78 } 79 } 80 } 81 82 83 @Override 84 public String toString() { 85 return "TestField{" + "i=" + i + ", d=" + d + ", f=" + f + ", l=" + l + ", s=" + s + '}'; 86 } 87 }
创建测试代码,测试一下如何使用赋值
public static void main(String[] args) { t0(); } public static void t0() { TestField tf1 = new TestField(); tf1.setValue("1_2000,2_2000"); System.out.println(tf1); tf1.addValue("3_2000,4_2000"); System.out.println(tf1); tf1.addValue("1_10000,5_2000"); System.out.println(tf1); }
输出结果:
1 --- exec-maven-plugin:1.2.1:exec (default-cli) @ com.dyf.tools.utils --- 2 TestField{i=2000, d=2000.0, f=0.0, l=0, s=0} 3 TestField{i=2000, d=2000.0, f=2000.0, l=2000, s=0} 4 TestField{i=12000, d=2000.0, f=2000.0, l=2000, s=2000} 5 ------------------------------------------------------------------------ 6 BUILD SUCCESS 7 ------------------------------------------------------------------------ 8 Total time: 0.766 s 9 Finished at: 2018-04-02T10:36:13+08:00
复杂运算方式
通常我们属性在参与计算的时候,比如,buff按照固定数值提高攻击力,按照比例提升攻击力等情况;
通常情况,这样的话,我给数值策划停供两个字段,一个字段配置的是属性的固定数值,
比如401-200,表示攻击力提升200点固定数值
还有一个万分比提升比例方式同样是:401-2000;表示攻击力需要提升20%;
这样牵涉的问题就是,在运算的时候,需要根据配置去找到对于的属性,做正常的操作;
在赋值运算之前我们需要先处理类型转换问题,
在此就不bb直接上辅助类吧:
1 package com.tools; 2 3 import java.math.BigDecimal; 4 import java.math.BigInteger; 5 6 /** 7 * 辅助类型转换,泛型类型转换 8 * <br> 9 * author 失足程序员<br> 10 * blog http://www.cnblogs.com/shizuchengxuyuan/<br> 11 * mail 492794628@qq.com<br> 12 * phone 13882122019<br> 13 */ 14 public class ConvertTypeUtil { 15 16 /** 17 * 常量类型 18 */ 19 public enum TypeCode { 20 /** 21 * 默认值,null 22 */ 23 Default(ConvertTypeUtil.class), 24 Boolean(java.lang.Boolean.class), 25 Char(char.class), 26 Date(java.util.Date.class), 27 String(java.lang.String.class), 28 Object(java.lang.Object.class), 29 Byte(java.lang.Byte.class, byte.class), 30 Short(java.lang.Short.class, short.class), 31 Integer(java.lang.Integer.class, int.class), 32 Long(java.lang.Long.class, long.class), 33 Float(java.lang.Float.class, float.class), 34 Double(java.lang.Double.class, double.class), 35 BigInteger(java.math.BigInteger.class), 36 BigDecimal(java.math.BigDecimal.class),; 37 38 private Class<?>[] clazzs; 39 40 private TypeCode(Class<?>... clazzs) { 41 this.clazzs = clazzs; 42 } 43 44 public Class<?>[] getClazzs() { 45 return clazzs; 46 } 47 48 /** 49 * 50 * @param clazz 51 * @return 52 */ 53 public static TypeCode getTypeCode(Class<?> clazz) { 54 if (clazz != null) { 55 TypeCode[] values = TypeCode.values(); 56 for (TypeCode value : values) { 57 for (Class<?> tmpClass : value.getClazzs()) { 58 if (tmpClass.equals(clazz)) { 59 return value; 60 } 61 } 62 } 63 } 64 return TypeCode.Default; 65 } 66 67 /** 68 * 69 * @param clazz 70 * @return 71 */ 72 public static TypeCode getTypeCode(String clazz) { 73 if (clazz != null) { 74 TypeCode[] values = TypeCode.values(); 75 for (TypeCode value : values) { 76 for (Class<?> tmpClass : value.getClazzs()) { 77 if (tmpClass.getName().equalsIgnoreCase(clazz) || tmpClass.getSimpleName().equalsIgnoreCase(clazz)) { 78 return value; 79 } 80 } 81 } 82 } 83 return TypeCode.Default; 84 } 85 86 } 87 88 /** 89 * 类型转换 90 * 91 * @param obj 92 * @param clazz 93 * @return 94 */ 95 public static Object changeType(Object obj, Class<?> clazz) { 96 97 if (obj == null || clazz.isInstance(obj) || clazz.isAssignableFrom(obj.getClass())) { 98 return obj; 99 } 100 101 TypeCode typeCode = TypeCode.getTypeCode(clazz); 102 103 return changeType(obj, typeCode, clazz); 104 } 105 106 /** 107 * 类型转换 108 * 109 * @param obj 110 * @param typeCode 111 * @param clazz 112 * @return 113 */ 114 public static Object changeType(Object obj, TypeCode typeCode, Class<?> clazz) { 115 /*如果等于,或者所与继承关系*/ 116 if (obj == null || clazz.isInstance(obj) || clazz.isAssignableFrom(obj.getClass())) { 117 return obj; 118 } 119 120 switch (typeCode) { 121 case Char: 122 throw new UnsupportedOperationException(); 123 case String: 124 return String.valueOf(obj); 125 case Boolean: 126 return Boolean.valueOf((String) changeType(obj, TypeCode.String, String.class)); 127 case Byte: 128 return Byte.valueOf((String) changeType(obj, TypeCode.String, String.class)); 129 case Short: 130 return Short.valueOf((String) changeType(obj, TypeCode.String, String.class)); 131 case Integer: 132 return Integer.valueOf((String) changeType(obj, TypeCode.String, String.class)); 133 case BigInteger: 134 return BigInteger.valueOf((Long) changeType(obj, TypeCode.Long, Long.class)); 135 case Long: 136 return Long.valueOf((String) changeType(obj, TypeCode.String, String.class)); 137 case Float: 138 return Float.valueOf((String) changeType(obj, TypeCode.String, String.class)); 139 case Double: 140 return Double.valueOf((String) changeType(obj, TypeCode.String, String.class)); 141 case BigDecimal: 142 return BigDecimal.valueOf((Long) changeType(obj, TypeCode.Long, Long.class)); 143 default: { 144 return obj; 145 } 146 } 147 } 148 149 /** 150 * 把对象转化成 Byte 151 * 152 * @param obj 153 * @return 154 */ 155 public static Byte toByte(Object obj) { 156 return (Byte) changeType(obj, TypeCode.Byte, Byte.class); 157 } 158 159 public static byte tobyte(Object obj) { 160 if (obj == null) { 161 return 0; 162 } 163 return (Byte) changeType(obj, TypeCode.Byte, Byte.class); 164 } 165 166 /** 167 * 把对象转化成 Short 168 * 169 * @param obj 170 * @return 171 */ 172 public static Short toShort(Object obj) { 173 return (Short) changeType(obj, TypeCode.Short, Short.class); 174 } 175 176 public static short toshort(Object obj) { 177 if (obj == null) { 178 return 0; 179 } 180 return (short) changeType(obj, TypeCode.Byte, Byte.class); 181 } 182 183 /** 184 * 把对象转化成 Integer 185 * 186 * @param obj 187 * @return 188 */ 189 public static Integer toInteger(Object obj) { 190 return (Integer) changeType(obj, TypeCode.Integer, Integer.class); 191 } 192 193 public static int toInt(Object obj) { 194 if (obj == null) { 195 return 0; 196 } 197 return (Integer) changeType(obj, TypeCode.Integer, Integer.class); 198 } 199 200 /** 201 * 把对象转化成 Long 202 * 203 * @param obj 204 * @return 205 */ 206 public static Long toLong(Object obj) { 207 return (Long) changeType(obj, TypeCode.Long, Long.class); 208 } 209 210 public static long tolong(Object obj) { 211 if (obj == null) { 212 return 0; 213 } 214 return (long) changeType(obj, TypeCode.Long, Long.class); 215 } 216 217 /** 218 * 把对象转化成 Float 219 * 220 * @param obj 221 * @return 222 */ 223 public static Float toFloat(Object obj) { 224 return (Float) changeType(obj, TypeCode.Float, Float.class); 225 } 226 227 public static float tofloat(Object obj) { 228 if (obj == null) { 229 return 0f; 230 } 231 return (Float) changeType(obj, TypeCode.Float, Float.class); 232 } 233 234 /** 235 * 把对象转化成 Double 236 * 237 * @param obj 238 * @return 239 */ 240 public static Double toDouble(Object obj) { 241 return (Double) changeType(obj, TypeCode.Double, Double.class); 242 } 243 244 /** 245 * 返回 0 246 * 247 * @param obj 248 * @return 249 */ 250 public static double todouble(Object obj) { 251 if (obj == null) { 252 return 0d; 253 } 254 return (double) changeType(obj, TypeCode.Double, Double.class); 255 } 256 257 /** 258 * 把对象转化为字符串 259 * 260 * @param obj 261 * @return 262 */ 263 public static String toString(Object obj) { 264 return (String) changeType(obj, TypeCode.String, String.class); 265 } 266 267 /** 268 * 如果异常返回 "" 269 * 270 * @param obj 271 * @return 272 */ 273 public static String toStr(Object obj) { 274 if (obj == null) { 275 return ""; 276 } 277 return (String) changeType(obj, TypeCode.String, String.class); 278 } 279 280 public static void main(String[] args) { 281 Object ob = 123; 282 try { 283 String str = (String) ob; 284 } catch (Exception e) { 285 e.printStackTrace(System.out); 286 287 } 288 String str = (String) changeType(ob, String.class); 289 } 290 291 }
属性的计算方式,我们现在扩展一下 类 FieldStruc
1 /** 2 * 设置属性,累加属性 3 * 4 * @param fieldTypeId 5 * @param source 6 * @param value 7 */ 8 public void sumFieldValue(int fieldTypeId, Object source, Object value) { 9 HashSet<Field> attset = getMapfByNumber().get(fieldTypeId); 10 if (attset != null) { 11 for (Field field : attset) { 12 FieldUtil.sumFieldValue(source, field, value); 13 } 14 } else { 15 System.out.println("属性ID不存在:" + fieldTypeId); 16 } 17 } 18 19 /** 20 * 设置属性,累加属性 21 * 22 * @param fieldName 23 * @param source 24 * @param value 25 */ 26 public void sumFieldValue(String fieldName, Object source, Object value) { 27 Field field = getMapByName().get(fieldName); 28 if (field != null) { 29 FieldUtil.sumFieldValue(source, field, value); 30 } else { 31 System.out.println("属性名字不存在:" + fieldName); 32 } 33 } 34 35 /** 36 * 属性字段做减法操作 37 * <br>非数值类型直接替换 38 * 39 * @param fieldTypeId 40 * @param source 41 * @param value 42 */ 43 public void subtractFieldValue(int fieldTypeId, Object source, Object value) { 44 HashSet<Field> attset = getMapfByNumber().get(fieldTypeId); 45 if (attset != null) { 46 for (Field field : attset) { 47 FieldUtil.subtractFieldValue(source, field, value); 48 } 49 } else { 50 System.out.println("属性ID不存在:" + fieldTypeId); 51 } 52 } 53 54 /** 55 * 属性字段做减法操作 56 * <br>非数值类型直接替换 57 * 58 * @param fieldName 59 * @param source 60 * @param value 61 */ 62 public void subtractFieldValue(String fieldName, Object source, Object value) { 63 Field field = getMapByName().get(fieldName); 64 if (field != null) { 65 FieldUtil.subtractFieldValue(source, field, value); 66 } else { 67 System.out.println("属性名字不存在:" + fieldName); 68 } 69 } 70 71 /** 72 * 乘以对于的值,如果是非数值类型,忽律 73 * 74 * @param fieldTypeId 75 * @param source 76 * @param value 77 */ 78 public void multiplyFieldValue(int fieldTypeId, Object source, Object value) { 79 HashSet<Field> attset = getMapfByNumber().get(fieldTypeId); 80 if (attset != null) { 81 for (Field field : attset) { 82 FieldUtil.multiplyFieldValue(source, field, value); 83 } 84 } else { 85 System.out.println("属性ID不存在:" + fieldTypeId); 86 } 87 } 88 89 /** 90 * 乘以对于的值,如果是非数值类型,忽律 91 * 92 * @param fieldName 93 * @param source 94 * @param value 95 */ 96 public void multiplyFieldValue(String fieldName, Object source, Object value) { 97 Field field = getMapByName().get(fieldName); 98 if (field != null) { 99 FieldUtil.multiplyFieldValue(source, field, value); 100 } else { 101 System.out.println("属性名字不存在:" + fieldName); 102 } 103 } 104 105 /** 106 * 设置属性 107 * 108 * @param fieldName 109 * @param source 110 * @param value 111 */ 112 public void setFieldValue(String fieldName, Object source, Object value) { 113 Field field = getMapByName().get(fieldName); 114 if (field != null) { 115 FieldUtil.setFieldValue(source, field, value); 116 } else { 117 System.out.println("属性名字不存在:" + fieldName); 118 } 119 } 120 121 /** 122 * 设置属性 123 * 124 * @param fieldTypeId 125 * @param source 126 * @param value 127 */ 128 public void setFieldValue(int fieldTypeId, Object source, Object value) { 129 HashSet<Field> attset = getMapfByNumber().get(fieldTypeId); 130 if (attset != null) { 131 for (Field field : attset) { 132 FieldUtil.setFieldValue(source, field, value); 133 } 134 } else { 135 System.out.println("属性ID不存在:" + fieldTypeId); 136 } 137 } 138 139 /** 140 * 第一个参数值 加上 第二个参数的属性值 141 * 142 * @param source1 143 * @param source2 144 */ 145 public void sumFieldValue(Object source1, Object source2) { 146 HashMap<String, Field> mapByName1 = this.getMapByName(); 147 for (Map.Entry<String, Field> entry : mapByName1.entrySet()) { 148 String key = entry.getKey(); 149 Field field = entry.getValue(); 150 /*读取第二个参数的属性值*/ 151 Object fieldValue = FieldUtil.getFieldValue(source2, field); 152 /*追加到抵押给参数的属性值*/ 153 FieldUtil.sumFieldValue(source1, field, fieldValue); 154 } 155 } 156 157 /** 158 * 第一个参数值 减去 第二个参数的属性值 159 * 160 * @param source1 161 * @param source2 162 */ 163 public void subtractFieldValue(Object source1, Object source2) { 164 HashMap<String, Field> mapByName1 = this.getMapByName(); 165 for (Map.Entry<String, Field> entry : mapByName1.entrySet()) { 166 String key = entry.getKey(); 167 Field field = entry.getValue(); 168 /*读取第二个参数的属性值*/ 169 Object fieldValue = FieldUtil.getFieldValue(source2, field); 170 /*追加到抵押给参数的属性值*/ 171 FieldUtil.subtractFieldValue(source1, field, fieldValue); 172 } 173 } 174 175 /** 176 * 乘以对于的值,如果是非数值类型,忽律 177 * 178 * @param source1 179 * @param source2 180 */ 181 public void multiplyFieldValue(Object source1, Object source2) { 182 HashMap<String, Field> mapByName1 = this.getMapByName(); 183 for (Map.Entry<String, Field> entry : mapByName1.entrySet()) { 184 String key = entry.getKey(); 185 Field field = entry.getValue(); 186 /*读取第二个参数的属性值*/ 187 Object fieldValue = FieldUtil.getFieldValue(source2, field); 188 /*追加到抵押给参数的属性值*/ 189 FieldUtil.multiplyFieldValue(source1, field, fieldValue); 190 } 191 } 192 193 /** 194 * 乘以对于的值,如果是非数值类型,忽律 195 * <br> 按照万分比配置的数值进行 1+(value/10000); 196 * 197 * @param source1 198 * @param source2 199 */ 200 public void multiplyFieldValueByRatio1(Object source1, Object source2) { 201 HashMap<String, Field> mapByName1 = this.getMapByName(); 202 for (Map.Entry<String, Field> entry : mapByName1.entrySet()) { 203 String key = entry.getKey(); 204 Field field = entry.getValue(); 205 /*读取第二个参数的属性值*/ 206 Object fieldValue = FieldUtil.getFieldValue(source2, field); 207 /*追加到抵押给参数的属性值*/ 208 FieldUtil.multiplyFieldValueByRatio1(source1, field, fieldValue); 209 } 210 } 211 212 /** 213 * source1 = source2 的字段属性值 * (source3 的字段属性值 / 100) 214 * 215 * @param source1 216 * @param source2 217 * @param source3 218 */ 219 public void setFieldValue1(Object source1, Object source2, Object source3) { 220 for (Map.Entry<String, Field> entry : mapByName.entrySet()) { 221 String key = entry.getKey(); 222 Field ms = entry.getValue(); 223 try { 224 if (ms.getType().isAssignableFrom(int.class)) { 225 FieldUtil.setFieldValue(source1, ms, ((Double) ((Double) FieldUtil.getFieldValue(source2, ms) * (Double) FieldUtil.getFieldValue(source3, ms) / 10000D)).intValue()); 226 } else if (ms.getType().isAssignableFrom(long.class)) { 227 FieldUtil.setFieldValue(source1, ms, ((Double) ((Double) FieldUtil.getFieldValue(source2, ms) * (Double) FieldUtil.getFieldValue(source3, ms) / 10000D)).longValue()); 228 } else if (ms.getType().isAssignableFrom(float.class)) { 229 FieldUtil.setFieldValue(source1, ms, ((Double) ((Double) FieldUtil.getFieldValue(source2, ms) * (Double) FieldUtil.getFieldValue(source3, ms) / 10000D)).floatValue()); 230 } else if (ms.getType().isAssignableFrom(double.class)) { 231 FieldUtil.setFieldValue(source1, ms, ((Double) FieldUtil.getFieldValue(source2, ms) * (Double) FieldUtil.getFieldValue(source3, ms) / 10000D)); 232 } else if (ms.getType().isAssignableFrom(byte.class)) { 233 FieldUtil.setFieldValue(source1, ms, ((Double) ((Double) FieldUtil.getFieldValue(source2, ms) * (Double) FieldUtil.getFieldValue(source3, ms) / 10000D)).byteValue()); 234 } else if (ms.getType().isAssignableFrom(short.class)) { 235 FieldUtil.setFieldValue(source1, ms, ((Double) ((Double) FieldUtil.getFieldValue(source2, ms) * (Double) FieldUtil.getFieldValue(source3, ms) / 10000D)).shortValue()); 236 } 237 } catch (Exception ex) { 238 System.out.println("addPercent" + ms.getName()); 239 ex.printStackTrace(System.out); 240 } 241 } 242 } 243 244 /** 245 * source1 = source2 的字段属性值 * (source3 的字段属性值 / 100) 246 * 247 * @param source1 248 * @param source2 249 * @param source3 250 */ 251 public void setFieldValue2(Object source1, Object source2, Object source3) { 252 for (Map.Entry<String, Field> entry : mapByName.entrySet()) { 253 Field ms = entry.getValue(); 254 try { 255 if (ms.getType().isAssignableFrom(int.class)) { 256 FieldUtil.setFieldValue(source1, ms, ((Double) ((Double) FieldUtil.getFieldValue(source2, ms) * (Double) FieldUtil.getFieldValue(source3, ms) / 100D)).intValue()); 257 } else if (ms.getType().isAssignableFrom(long.class)) { 258 FieldUtil.setFieldValue(source1, ms, ((Double) ((Double) FieldUtil.getFieldValue(source2, ms) * (Double) FieldUtil.getFieldValue(source3, ms) / 100D)).longValue()); 259 } else if (ms.getType().isAssignableFrom(float.class)) { 260 FieldUtil.setFieldValue(source1, ms, ((Double) ((Double) FieldUtil.getFieldValue(source2, ms) * (Double) FieldUtil.getFieldValue(source3, ms) / 100D)).floatValue()); 261 } else if (ms.getType().isAssignableFrom(double.class)) { 262 FieldUtil.setFieldValue(source1, ms, ((Double) FieldUtil.getFieldValue(source2, ms) * (Double) FieldUtil.getFieldValue(source3, ms) / 10000D)); 263 } else if (ms.getType().isAssignableFrom(byte.class)) { 264 FieldUtil.setFieldValue(source1, ms, ((Double) ((Double) FieldUtil.getFieldValue(source2, ms) * (Double) FieldUtil.getFieldValue(source3, ms) / 100D)).byteValue()); 265 } else if (ms.getType().isAssignableFrom(short.class)) { 266 FieldUtil.setFieldValue(source1, ms, ((Double) ((Double) FieldUtil.getFieldValue(source2, ms) * (Double) FieldUtil.getFieldValue(source3, ms) / 100D)).shortValue()); 267 } 268 } catch (Exception ex) { 269 System.out.println("addPercent" + ms.getName()); 270 ex.printStackTrace(System.out); 271 } 272 } 273 } 274 275 /** 276 * 277 * @param source1 278 * @param source2 279 * @param ratio 280 */ 281 public void setFieldValueByFloat(Object source1, Object source2, float ratio) { 282 for (Map.Entry<String, Field> entry : mapByName.entrySet()) { 283 Field ms = entry.getValue(); 284 try { 285 if (ms.getType().isAssignableFrom(int.class)) { 286 FieldUtil.setFieldValue(source1, ms, ((Double) ((Double) FieldUtil.getFieldValue(source2, ms) * ratio)).intValue()); 287 } else if (ms.getType().isAssignableFrom(long.class)) { 288 FieldUtil.setFieldValue(source1, ms, ((Double) ((Double) FieldUtil.getFieldValue(source2, ms) * ratio)).longValue()); 289 } else if (ms.getType().isAssignableFrom(float.class)) { 290 FieldUtil.setFieldValue(source1, ms, ((Double) ((Double) FieldUtil.getFieldValue(source2, ms) * ratio)).floatValue()); 291 } else if (ms.getType().isAssignableFrom(double.class)) { 292 FieldUtil.setFieldValue(source1, ms, ((Double) FieldUtil.getFieldValue(source2, ms) * ratio)); 293 } else if (ms.getType().isAssignableFrom(byte.class)) { 294 FieldUtil.setFieldValue(source1, ms, ((Double) ((Double) FieldUtil.getFieldValue(source2, ms) * ratio)).byteValue()); 295 } else if (ms.getType().isAssignableFrom(short.class)) { 296 FieldUtil.setFieldValue(source1, ms, ((Double) ((Double) FieldUtil.getFieldValue(source2, ms) * ratio)).shortValue()); 297 } 298 } catch (Exception ex) { 299 System.out.println("addPercent" + ms.getName()); 300 ex.printStackTrace(System.out); 301 } 302 } 303 } 304 305 /** 306 * 乘以对于的值,如果是非数值类型,忽律 307 * <br> 按照百分比配置的数值进行 1+(value/100); 308 * 309 * @param source1 310 * @param source2 311 */ 312 public void multiplyFieldValueByRatio2(Object source1, Object source2) { 313 HashMap<String, Field> mapByName1 = this.getMapByName(); 314 for (Map.Entry<String, Field> entry : mapByName1.entrySet()) { 315 String key = entry.getKey(); 316 Field field = entry.getValue(); 317 /*读取第二个参数的属性值*/ 318 Object fieldValue = FieldUtil.getFieldValue(source2, field); 319 /*追加到抵押给参数的属性值*/ 320 FieldUtil.multiplyFieldValueByRatio2(source1, field, fieldValue); 321 } 322 } 323 324 /** 325 * 如果有一个属性不为 0 就 返回 false 326 * 327 * @param source 328 * @return 329 */ 330 public boolean isFieldValueZore(Object source) { 331 HashMap<String, Field> mapByName1 = this.getMapByName(); 332 for (Map.Entry<String, Field> entry : mapByName1.entrySet()) { 333 String key = entry.getKey(); 334 Field field = entry.getValue(); 335 if (FieldUtil.isZore(field, source) != 0) { 336 return false; 337 } 338 } 339 return true; 340 } 341 342 /** 343 * 如果属性小于0.直接设置0; 344 * 345 * @param source 346 */ 347 public void clearFieldValueZore(Object source) { 348 HashMap<String, Field> mapByName1 = this.getMapByName(); 349 for (Map.Entry<String, Field> entry : mapByName1.entrySet()) { 350 String key = entry.getKey(); 351 Field field = entry.getValue(); 352 if (FieldUtil.isNumberFrom(field) && FieldUtil.isZore(field, source) < 0) { 353 FieldUtil.setFieldValue(source, field, 0); 354 } 355 } 356 } 357 358 /** 359 * 所有属性都归0; 360 * 361 * @param source 362 */ 363 public void clearZore(Object source) { 364 HashMap<String, Field> mapByName1 = this.getMapByName(); 365 for (Map.Entry<String, Field> entry : mapByName1.entrySet()) { 366 String key = entry.getKey(); 367 Field field = entry.getValue(); 368 if (FieldUtil.isNumberFrom(field)) { 369 FieldUtil.setFieldValue(source, field, 0); 370 } 371 } 372 } 373 374 /** 375 * 376 * @param source1 377 * @param ratio 378 */ 379 public void multiplyValue(Object source1, float ratio) { 380 HashMap<String, Field> mapByName1 = this.getMapByName(); 381 for (Map.Entry<String, Field> entry : mapByName1.entrySet()) { 382 Field field = entry.getValue(); 383 /*追加到抵押给参数的属性值*/ 384 FieldUtil.multiplyValue(source1, field, ratio); 385 } 386 } 387 388 /** 389 * 390 * @param source1 391 * @param ratio 392 */ 393 public void divideValue(Object source1, float ratio) { 394 HashMap<String, Field> mapByName1 = this.getMapByName(); 395 for (Map.Entry<String, Field> entry : mapByName1.entrySet()) { 396 Field field = entry.getValue(); 397 /*追加到指定给参数的属性值*/ 398 FieldUtil.divideValue(source1, field, ratio); 399 } 400 }
增加测试函数试一下
1 public static void t1() { 2 TestField tf1 = new TestField(); 3 TestField tf2 = new TestField(); 4 tf1.addValue("1_2000,2_2000"); 5 tf2.addValue("1_2000,2_2000"); 6 tf1.addValue("3_2000,4_2000"); 7 tf2.addValue("3_2000,4_2000"); 8 tf1.addValue("1_10000,5_2000"); 9 tf2.addValue("1_10000,5_3000"); 10 System.out.println(tf1); 11 System.out.println(tf2); 12 FIELD_STRUC.multiplyFieldValue(tf1, tf2); 13 System.out.println("倍率:" + tf1); 14 } 15 16 public static void t2() { 17 TestField tf1 = new TestField(); 18 TestField tf2 = new TestField(); 19 tf1.addValue("1_2000,2_2000"); 20 tf2.addValue("1_2000,2_2000"); 21 tf1.addValue("3_2000,4_2000"); 22 tf2.addValue("3_2000,4_2000"); 23 tf1.addValue("1_10000,5_2000"); 24 tf2.addValue("1_10000,5_3000"); 25 System.out.println(tf1); 26 System.out.println(tf2); 27 FIELD_STRUC.multiplyFieldValueByRatio1(tf1, tf2); 28 System.out.println("万分比倍率:" + tf1); 29 }
测试结果如下:
1 --- exec-maven-plugin:1.2.1:exec (default-cli) @ com.dyf.tools.utils --- 2 TestField{i=2000, d=2000.0, f=0.0, l=0, s=0} 3 TestField{i=2000, d=2000.0, f=2000.0, l=2000, s=0} 4 TestField{i=12000, d=2000.0, f=2000.0, l=2000, s=2000} 5 TestField{i=12000, d=2000.0, f=2000.0, l=2000, s=2000} 6 TestField{i=12000, d=2000.0, f=2000.0, l=2000, s=3000} 7 倍率:TestField{i=144000000, d=4000000.0, f=4000000.0, l=4000000, s=-29312} 8 TestField{i=12000, d=2000.0, f=2000.0, l=2000, s=2000} 9 TestField{i=12000, d=2000.0, f=2000.0, l=2000, s=3000} 10 万分比倍率:TestField{i=26400, d=2400.0, f=2400.0, l=2400, s=2600} 11 ------------------------------------------------------------------------ 12 BUILD SUCCESS 13 ------------------------------------------------------------------------ 14 Total time: 0.788 s 15 Finished at: 2018-04-02T10:50:16+08:00 16 Final Memory: 11M/309M 17 ------------------------------------------------------------------------
我们日常属性中肯定不允许存在负属性
FIELD_STRUC.clearFieldValueZore(tf1);
System.out.println("清理小于0的属性值:" + tf1);
所有属性通常咋计算完成后需要做清理负值的运算;
1 --- exec-maven-plugin:1.2.1:exec (default-cli) @ com.dyf.tools.utils --- 2 TestField{i=2000, d=2000.0, f=0.0, l=0, s=0} 3 TestField{i=2000, d=2000.0, f=2000.0, l=2000, s=0} 4 TestField{i=12000, d=2000.0, f=2000.0, l=2000, s=2000} 5 TestField{i=12000, d=2000.0, f=2000.0, l=2000, s=2000} 6 TestField{i=12000, d=2000.0, f=2000.0, l=2000, s=3000} 7 倍率:TestField{i=144000000, d=4000000.0, f=4000000.0, l=4000000, s=-29312} 8 清理小于0的属性值:TestField{i=144000000, d=4000000.0, f=4000000.0, l=4000000, s=0} 9 TestField{i=12000, d=2000.0, f=2000.0, l=2000, s=2000} 10 TestField{i=12000, d=2000.0, f=2000.0, l=2000, s=3000} 11 万分比倍率:TestField{i=26400, d=2400.0, f=2400.0, l=2400, s=2600} 12 ------------------------------------------------------------------------ 13 BUILD SUCCESS
属性的辅助计算器就算完成,不会漏掉属性,增加,变更属性是不是更便捷方便,也减少了出错概率
最后提高一下源码,已经测试类;
好了,你或许还有更好的处理方式,不如我们交换一下吧。各位大佬;
跪求保留标示符 /** * @author: Troy.Chen(失足程序员, 15388152619) * @version: 2021-07-20 10:55 **/ C#版本代码 vs2010及以上工具可以 java 开发工具是netbeans 和 idea 版本,只有项目导入如果出现异常,请根据自己的工具调整 提供免费仓储。 最新的代码地址:↓↓↓ https://gitee.com/wuxindao 觉得我还可以,打赏一下吧,你的肯定是我努力的最大动力