鍍金池/ 問答/Java  網(wǎng)絡(luò)安全/ 如何優(yōu)化if判斷中,極其長的條件?

如何優(yōu)化if判斷中,極其長的條件?

目前需要寫一個(gè)判斷完整度的方法
A實(shí)體類共有20個(gè)字段,其中12個(gè)字段參與計(jì)算,計(jì)作:a1到a12
B實(shí)體類共有16個(gè)字段,其中8個(gè)字段參與計(jì)算,計(jì)作:b1到b8
C實(shí)體類共有19個(gè)字段,其中10個(gè)字段參與計(jì)算,計(jì)作:c1到c10
所有30個(gè)字段都不為空才算完整

目前的判斷語句為:

if (!StringUtils.isEmpty(a1) && ...
    && !StringUtils.isEmpty(c10)){
    return true;
}

目前的代碼很長,是否可以簡單優(yōu)化?為什要那樣優(yōu)化?

回答
編輯回答
兮顏

@NotEmpty

2018年1月24日 03:11
編輯回答
傲寒

if(m_state==1)
{
switch(m_tSpeed)
{
case 1:
....
}

}
else if(m_state==2)
{
同上
}

大概意思就是這樣,可以把一個(gè)判斷提出來先做,然后再做另一個(gè)判斷!

2018年4月17日 16:10
編輯回答
練命

String[] strings = {"a1",null,"a3","c1","c3","d1", "d2","d3"};
boolean flag = Arrays.stream(strings).anyMatch(StringUtils::isEmpty);

熟悉流處理 很多代碼都可以簡化

2017年11月7日 11:52
編輯回答
青瓷

可以使用 Hibernate Validator
圖片描述
這里有一篇使用介紹文章 https://www.cnblogs.com/xiaog...

2018年4月23日 23:27
編輯回答
我不懂

可以嘗試一下正則表達(dá)式

2018年1月6日 07:09
編輯回答
礙你眼

可以用斷言assert , Assert.noNullElements(new Object[]{1,"222"},"所有字段都不能為空"); 三個(gè)類 每個(gè)類中各加一個(gè)方法判斷自己的字段,調(diào)用這三個(gè)方法,或者 寫三次Assert.noNullElements(new Object[]{1,"222"},"所有字段都不能為空");分別傳入各個(gè)類的字段。

2018年8月8日 01:03
編輯回答
陌顏

把判斷條件抽離,歸類。
通過函數(shù)語義式的調(diào)用返回結(jié)果來判斷,好修改,也好閱讀。
比如if (validationA() && validationB())

2017年4月21日 01:28
編輯回答
厭惡我

看題主的問題,雖然直接每個(gè)對象每個(gè)字段都去get判空是可以,但是這樣的代碼明顯不方便維護(hù),而且可能越加越多,因此我分析主要需要解決以下兩個(gè)問題

  1. 每個(gè)實(shí)體類中的字段并不是所有字段都需要判空,所以這里會有修改的隱藏需求(增加或減少需要判斷的字段)
  2. 如果解決第一步,能將需要校驗(yàn)的字段篩選出來,那剩下的問題就是如何將所有的字段值取出來加以判斷

針對這兩個(gè)問題,我認(rèn)為

  1. 問題1可以通過自定義注解來標(biāo)示一下需要校驗(yàn)的字段,用注解標(biāo)示字段后,在需要增加或減少字段校驗(yàn),只需要修改對應(yīng)實(shí)體類里的屬性注解即可,不需要再修改校驗(yàn)類
  2. 問題2,取值出來,自然想到是反射了

這就有了一下的代碼:

首先是標(biāo)注的注解EmptyCheck

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface EmptyCheck {
}

然后注解到一個(gè)實(shí)體類A中的字段里,其中a1,a3字段需要判空,a2字段不需要

@Getter
@Setter
public class A {

    @EmptyCheck
    private String a1;

    private String a2;

    @EmptyCheck
    private String a3;
}

以上是準(zhǔn)備工作,接下來就是寫如何校驗(yàn)了,我采用了一個(gè)校驗(yàn)類EmptyCheckUtils,把所有校驗(yàn)方法放到里面了
既然是對于A,B之類的實(shí)體類對象進(jìn)行校驗(yàn),那第一個(gè)提供的方法,就是針對所有的實(shí)體類對象進(jìn)行的校驗(yàn)isAllNotEmpty,判斷所有對象的所有有EmptyCheck標(biāo)注的字段值是否都不為空

/**
     * 判斷所有對象的所有有EmptyCheck標(biāo)注的字段值是否都不為空
     * @param objects
     * @return
     */
    public static Boolean isAllNotEmpty(Object ... objects){
        return Arrays.stream(objects).allMatch(EmptyCheckUtils::isNotEmpty);
    }

接下來就是單個(gè)對象的判斷方法isNotEmpty

/**
     * 判斷一個(gè)對象的所有有EmptyCheck標(biāo)注的字段值是否都不為空
     * @param object
     * @return
     */
    public static Boolean isNotEmpty(Object object){
        Class tClass = object.getClass();
                // 獲取該類的所有字段
        return EmptyCheckUtils.getAllField(tClass)
                              // 過濾掉沒有標(biāo)注EmptyCheck注解的字段
                              .filter(EmptyCheckUtils::isEmptyCheckField)
                              // 獲取字段的值
                              .map(field -> EmptyCheckUtils.getValue(object, field))
                              // 判斷值是否為空
                              .allMatch(EmptyCheckUtils::isObjectNotEmpty);
    }

最后就是其他的輔助方法了

   /**
     * 根據(jù)目標(biāo)class類獲取該類下的所有字段(除靜態(tài)屬性字段)
     * @param tClass
     * @return
     */
    private static Stream<Field> getAllField(Class tClass) {
        Field[] dFields = tClass.getDeclaredFields();
        return Arrays.stream(dFields)
                      // 去掉靜態(tài)屬性
                     .filter(field -> !Modifier.isStatic(field.getModifiers()));
    }
    
    /**
     * 判斷該字段field是否有注解EmptyCheck
     * @param field
     * @return
     */
    private static Boolean isEmptyCheckField(Field field){
        EmptyCheck annotation = field.getAnnotation(EmptyCheck.class);
        return Objects.nonNull(annotation);
    }

    /**
     * 根據(jù)字段field和對象object,獲取該對象上field的值(基于get方法獲?。?     * @param object
     * @param field
     * @return
     */
    public static Object getValue(Object object, Field field){
        Object value = null;
        String fieldName = field.getName();
        try {
            Method method = object.getClass().getMethod(UtilsConstants.GETTER + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1, fieldName.length()));
            value = method.invoke(object);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return value;
    }

   /**
     * 判斷該值是否為空,可以根據(jù)該值對象去定制化判空方式
     * @param object
     * @return
     */
    public static Boolean isObjectNotEmpty(Object object){
        // 各種類型的判空
        // 這里只是簡單的用了一個(gè)Null判空
        return Objects.nonNull(object);
    }

測試類:

public static void main(String[] args) {
        A a = new A();
        System.out.println(EmptyCheckUtils.isAllNotEmpty(a));
        a.setA1("1");
        System.out.println(EmptyCheckUtils.isAllNotEmpty(a));
        a.setA2("2");
        System.out.println(EmptyCheckUtils.isAllNotEmpty(a));
        a.setA3("3");
        System.out.println(EmptyCheckUtils.isAllNotEmpty(a));
    }
   

運(yùn)行結(jié)果

clipboard.png

結(jié)果可以看到,由于是a2屬性不需要判空,所有只有等a3設(shè)置完值后,判斷結(jié)果才會為true

最后說明:為了方便展示,才將業(yè)務(wù)校驗(yàn)類EmptyCheckUtils中填充了很多和業(yè)務(wù)無關(guān)的校驗(yàn)方法,因此輔助方法中除了和業(yè)務(wù)有關(guān)的isObjectNotEmpty方法,其他的getValueisEmptyCheckFieldgetAllField等方法建議拆分到其他工具類中,保持業(yè)務(wù)方法類和其他輔助工具方法類的健壯穩(wěn)定性哈

2018年4月7日 11:48
編輯回答
終相守

維護(hù)一個(gè)需要驗(yàn)證的字段名數(shù)組,for...in循環(huán)遍歷對象屬性+一個(gè)flag=true,如果是需要遍歷的則isEmpty驗(yàn)證,如果不是continue。出現(xiàn)空了flag=false就break(如果三個(gè)實(shí)體需要校驗(yàn)的字段名沒有重復(fù),把三個(gè)對象union一份出來單獨(dú)做校驗(yàn))

2017年8月4日 21:01
編輯回答
枕頭人

編寫一個(gè)新函數(shù)?

2017年12月8日 12:23