【问题标题】:Alias for expressions in javajava中表达式的别名
【发布时间】:2020-09-09 18:26:39
【问题描述】:

我在 java 中有一个 if 条件,它在代码中的许多地方再次出现。我想避免一次又一次地写整个条件。在 C 语言中,我可以使用#define 来做到这一点

#define cond ((i==2) && (j==5) && (k==8))

int main() {
    if(cond)
}

如何在 java 中实现相同的功能?我可能可以创建另一种评估这种情况的方法 -

  main() {
        if(cond())
    }

cond() {
    return (i==2) && (j==5) && (k==8);
}

但我想知道是否可以避免创建另一个函数。


更新 -

我意识到我应该添加更多细节/编辑来支持我的论点。假设我有 2 个条件,我想同时检查这两个条件-

 #define cond258 ((i==2) && (j==5) && (k==8))
 #define cond369 ((i==3) && (j==6) && (k==9))

我可以创建 2 个函数 -

cond258(i, j, k) {
        return (i==2) && (j==5) && (k==8);
    }
cond369(i, j, k) {
        return (i==3) && (j==6) && (k==9);
    }

这对我来说似乎不是一个好方法。这两个函数都在做类似的事情,所以它们应该被转换为单个函数 -

cond(i, j, k, first, second, third) {
        return (i==first) && (j==second) && (k==third);
}

但这使我的 if 条件不可读 -

if(cond(i, j, k, 2, 5, 8) || cond(i, j, k, 3, 6, 9))

所以如果我可以有一些别名,我可以简单地写成

if(cond258 || cond369)

【问题讨论】:

  • 为什么要避免创建另一个函数?
  • 这能回答你的问题吗? Can I have macros in Java source files
  • 只需将方法添加到适当的类。写Java的时候不要尝试写C,结果会一团糟(反之亦然)。
  • @Steve ,我对原始问题添加了一些更新。希望这可以解释我的情况。
  • '这对我来说似乎不是一个好方法。两个函数都在做类似的事情,所以它们应该被转换为单个函数'——同样的推理如何不适用于宏? if (cond258(i, j, k))怎么错了,if (cond258)突然OK了?

标签: java


【解决方案1】:

我相信如果不编写另一个函数就无法这样做,或者至少不建议/不实用。为条件语句编写另一种方法实际上是重构您的代码,在这种情况下为Decompose conditional

【讨论】:

  • 我同意上面的答案,但是我想补充一点,如果您选择将此条件提取到函数中,请尝试给它一个有意义的名称来代表您提取的测试。这实际上是一个很好的做法。
【解决方案2】:

你可以这样做。

private static int i = 2;
private static int j = 5;
private static int k = 8;
private static Supplier<Boolean> cond  = ()->i == 2 && j == 5 && k == 8;    
public static void main(String[] args) {
    System.out.println(cond.get()); // prints true
    k = 11;
    System.out.println(cond.get()); // prints false
}
  • 我将它们设为静态,以便它们可以在任何上下文(静态或实例)中使用。
  • 变量不能是局部的,因为 lambda 中的局部值必须是有效的最终值。
  • 它们将与实例化包含它们的类的其他类共享。

这是一个使用实例字段的示例。

int ii = 2;
int jj = 5;
int kk = 8;

Supplier<Boolean> cond = () -> ii == 2 && jj == 5 && kk == 8;
    
public static void main(String[] args) {

    ThisClass tc = new ThisClass();

    // static context so they need to be qualified.
    System.out.println(tc.cond.get()); // prints true
    tc.kk = 11;
    System.out.println(tc.cond.get()); // prints false
    tc.foo();
}
public void foo() {
    // instance method so cond and kk do not need to be qualified
    kk = 8;
    System.out.println(cond.get()); // true
}

【讨论】:

    【解决方案3】:

    这就是我解决这个问题的方法-

    创建了一个新类 Triplet -

    public class Triplet <F, S, T> {
        
        public F first;
        public S second;
        public T third;
        
        @Override
        public boolean equals(Object obj) {
    
            if (obj instanceof Triplet <?,?,?>) {
                
                Triplet <?, ?, ?> triplet = (Triplet <?, ?, ?>) obj;            
                return (this.first.equals(triplet.first) && this.second.equals(triplet.second) && this.third.equals(triplet.third));
            } 
            else 
                return false;
        }
    
        
        public Triplet (F first, S second, T third) throws NullPointerException {
            if(first==null|| second==null || third==null)
                throw new NullPointerException("Can't create object with null values for first or second or third");
            this.first = first;
            this.second = second;
            this.third = third;
        }   
    }
    

    创建静态三元组 -

    public static final Triplet<Integer, Integer, Integer> triplet258 = new Triplet<Integer, Integer, Integer>(2, 5, 8);
    public static final Triplet<Integer, Integer, Integer> triplet369 = new Triplet<Integer, Integer, Integer>(3, 6, 9);
    

    我的 if 条件变为 -

    Triplet<Integer, Integer, Integer> myTriplet = new Triplet<Integer, Integer, Integer>(i, j, k);
    
    if(myTriplet.equals(triplet258) || myTriplet.equals(triplet369))
    

    【讨论】:

      猜你喜欢
      • 2021-06-06
      • 1970-01-01
      • 1970-01-01
      • 2014-11-11
      • 1970-01-01
      • 1970-01-01
      • 2011-11-13
      • 1970-01-01
      • 2010-09-29
      相关资源
      最近更新 更多