序言
知道大家都懶,都挺忙的,於是提出給大家提供一個屬性計算器功能,
在游戲中每一個場景對象都有着自己的屬性,例如移動速度,攻擊力,防御力,幸運值,三維等一系列屬性值
屬性牽涉的最多的幾個問題,屬性的常規值,也就是裸屬性,裝備的屬性值,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
屬性的輔助計算器就算完成,不會漏掉屬性,增加,變更屬性是不是更便捷方便,也減少了出錯概率
最后提高一下源碼,已經測試類;
好了,你或許還有更好的處理方式,不如我們交換一下吧。各位大佬;