游戏开发——属性计算器辅助工具——知道大家都懒

序言

知道大家都懒,都挺忙的,于是提出给大家提供一个属性计算器功能,

在游戏中每一个场景对象都有着自己的属性,例如移动速度,攻击力,防御力,幸运值,三维等一系列属性值

属性牵涉的最多的几个问题,属性的常规值,也就是裸属性,装备的属性值,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 }
View Code

属性的计算方式,我们现在扩展一下 类 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     }
View Code

测试结果如下:

 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

属性的辅助计算器就算完成,不会漏掉属性,增加,变更属性是不是更便捷方便,也减少了出错概率

最后提高一下源码,已经测试类;

好了,你或许还有更好的处理方式,不如我们交换一下吧。各位大佬;

代码下载

原文地址:https://www.cnblogs.com/shizuchengxuyuan/p/8691287.html