簡體   English   中英

如何在Java中打開equals語句以接受多個參數?

[英]How can I open up my equals statements to accept more than one parameter in Java?

我有一個夢想....

在這個夢想中,我可以替換以下結構:

if(aLongVariableName.equals(classInstance.aPropertyOfThatInstance) ||  
   aLongVariableName.equals(classInstance.aDifferentProperty)){  
    ...  
}

if(aLongVariableName.equals(classInstance.aDifferentProperty || aPropertyOfThatInstance)){ 
   ...  
}

我認為后者更簡潔,更易於閱讀。 我確信應該可以public void readUnlimitedVariables(Variable ... vars)什么,因為可以使用這種簽名public void readUnlimitedVariables(Variable ... vars)聲明方法,該方法采用逗號分隔的變量(與||甚至&&相對)。

例如,這可以向任何返回布爾值的對象開放:

if(myLovelyInstance instanceof AwesomeClass && EpicClass){
    ...
}

myLovelyInstance實現AwesomeClass && EpicClass

這在Java中可行嗎? 到目前為止,通過谷歌搜索還是在SO上,我都沒有找到任何東西。 如果不是在普通Java中,是否有任何第三方軟件包(如Lombok或lambdaJ)允許這樣做? 如果不是,這是否是任何語言的功能? 對我來說,這似乎很直觀,但我從未在任何地方看到它。

這在Java中可行嗎?

沒有。

|| 運算符采用兩個布爾操作數。 沒有辦法改變這一點。 Java不允許您重載運算符或以其他方式“擴展語言語法”。

您可能獲得的最接近的結果是為等於定義一個重載,如下所示:

public boolean equals(Object ... others) {
    for (Object other: others) {
        if (this.equals(other)) {
            return true;
        }
    }
    return false;
}

並像這樣使用它:

if (aLongVariableName.equals(classInstance.aDifferentProperty,
                             classInstance.anotherProperty)) {
    ...  
}

...這根本不是很接近。 (還有一個非常糟糕的主意,IMO)

實際上,我想不出任何支持類似於您所提議語法的語言。 令我吃驚的是,將其含糊不清,使它成為一個合理的構架的可能性太大。

為了提高可讀性,如果檢查次數足夠少,則可以僅使用簡單變量。

例如(對於任何類型的對象都是相同的)

boolean isPDFFile  = extension.equalsIgnoreCase("PDF");
boolean isHTMLFile = extension.equalsIgnoreCase("html");

if (isPDFFile || isHTMLFile ) {
   // do your processing
}

如果您使用String,則Regulare Expression是另一種方式:

if (extension.matches("PDF|HTML")) {
   // do your processing
}

有時候,簡單勝於聰明!

您能考慮一種不好的做法嗎? (我是Java的新手,所以我可能發明了輪子,或者只是制作了bulsh * t :))

public class Main {
    public static <Type> boolean equalsVariadicOr(Type toComp, Type ... args) {
                for (Type arg : args) {
                        if (toComp.equals(arg)) {
                                return true;
                        }
                }
                return false;
        }

        public static <Type> boolean equalsVariadicAnd(Type toComp, Type ... args) {
                for (Type arg : args) {
                        if (!toComp.equals(arg)) {
                                return false;
                        }
                }
                return true;
        }

        public static void main(String args[]) {
                String testcaseAllA[]  = new String[] {"a", "a", "a", "a", "a", "a", "a", "a", "a", "a"};
                String testcaseWithB[] = new String[] {"b", "a", "a", "a", "a", "a", "a", "a", "a", "a"};
                System.out.println(equalsVariadicAnd("a", testcaseAllA));
                System.out.println(equalsVariadicAnd("b", testcaseWithB));
                System.out.println(equalsVariadicOr("b", testcaseWithB));
                System.out.println(equalsVariadicOr("a", testcaseAllA));
        }
}

如果答案是否定的,也許OP會覺得有用嗎?

您可以使用varargs和Lombok的擴展方法獲得非常相似的東西:

  1. 在實用程序類中定義以下靜態方法:

     package test; public final class Util { private Util() {} public static boolean eqOr(Object tthis, Object ... those) { for (Object that : those) { if (tthis.equals(that)) return true; } return false; } public static boolean eqAnd(Object tthis, Object ... those) { for (Object that : those) { if (!tthis.equals(that)) return false; } return true; } } 
  2. 使用Lombok來使eqAndeqOr成為擴展方法:

     package test; @lombok.experimental.ExtensionMethod({test.Util.class}) public class Work { public static void main(String[] args) { System.out.println("a".eqOr("b", "c", "a")); System.out.println("a".eqOr("b", "c")); System.out.println("a".eqAnd("a", "a", "a")); System.out.println("a".eqAnd("a", "a", "c")); } } 

    顯然,如果您不喜歡lombok,則可以像常規靜態方法一樣使用它們。

在Java中是不可能的。 ||的參數 必須是boolean s,而.equals決定為時已晚,因為它不會同時獲得兩個值,而只是一個boolean

為了使其成為可能,必須更改Java語言規范。 我看不到會有這種趨勢,因此您應該告訴Java維護人員您希望擁有這種趨勢。 即使他們接受了它,也可能要花幾年時間才能達到語言規范,然后再花數年時間才能部署到大多數Java安裝中。

不要忘記封裝。

您通常可以使用實例方法來清理代碼:

您可以執行以下操作來代替冗長而令人困惑的if語句:

if (classInstance.matches(reallyLongVariableName)) {
    doStuff();
}

您可以通過以下方法掩蓋丑陋:

class LongNamedObject {

    String propertyWithNameThatIsLong;
    String anotherLongNamedProperty;

    public boolean matches(String s) {
        return ( s.equals(propertyWithNameThatIsLong) ||
                 s.equals(anotherLongNamedProperty) );
    }
}

用表達性名稱編寫布爾方法是使代碼易於閱讀的好方法。

因此,通常您會看到這樣的混亂情況:

if (userInputFile != null && userInputFile.getAbolutePath() != null 
      && user != null && user.getAccessRules() != null 
      && userHasAccess(user, userInputFile) {
    doStuff();
}

它可能看起來像這樣:

if (isValid(userInputFile, user)) {
    doStuff();
}

您可以通過以下方法掩蓋丑陋:

private boolean isValid(File f, User u) {
    if (u == null || f == null) {
        return false;
    }
    if (f.getAbsolutePath() == null) {
        return false;
    }
    if (u.getAccessRules() == null) {
        return false;
    }
    return userHasAccess(u, f);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM