如何打开我的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的扩展方法获得非常类似的东西:

  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 ,并且.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); }