如何打开我的equals语句以接受Java中的多个参数?
我有一个梦想….
在这个梦想中,我可以取代以下构造:
if(aLongVariableName.equals(classInstance.aPropertyOfThatInstance) || aLongVariableName.equals(classInstance.aDifferentProperty)){ ... }
同
if(aLongVariableName.equals(classInstance.aDifferentProperty || aPropertyOfThatInstance)){ ... }
我认为后者更简洁,更容易阅读。 我确信应该可以使用这种签名public void readUnlimitedVariables(Variable ... vars)
来声明方法,它采用逗号分隔的变量(而不是||
或者&&
)。
这可以打开到返回布尔值的任何东西,例如:
if(myLovelyInstance instanceof AwesomeClass && EpicClass){ ... }
其中myLovelyInstance
实现了AwesomeClass && EpicClass
这在Java中可行吗? 到目前为止,我还没有找到任何关于谷歌的信息。 如果它不是在Java中,那么是否有任何第三方软件包如Lombok或lambdaJ可以允许这样做? 如果不是这样,如果这是任何语言的特征? 这对我来说似乎很直观,但我没有在任何地方看到它。
这在Java中可行吗?
没有。
||
operator有两个布尔操作数。 没有办法改变这一点。 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很陌生,所以我可能会发明轮子或者只是犯规*)))
public class Main { public static boolean equalsVariadicOr(Type toComp, Type ... args) { for (Type arg : args) { if (toComp.equals(arg)) { return true; } } return false; } public static 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的扩展方法获得非常类似的东西:
-
在实用程序类中定义以下静态方法:
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; } }
-
使用Lombok使
eqAnd
和eqOr
成为扩展方法: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
,并且.equals
决定为时已晚,因为它不能同时获得两个值,只是一个boolean
。
为了使其成为可能,必须更改Java语言规范。 我无法看到这样的趋势,所以你应该告诉Java的维护者你想拥有它。 即使他们接受它,也可能需要数年才能达到语言规范,然后需要数年时间才能部署到大多数Java安装中。
不要忘记ecapsulation。
您通常可以使用实例方法清理代码:
你可以这样做,而不是冗长,令人困惑的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); }