【问题标题】:Java: Ternary with no return. (For method calling)Java:没有回报的三元。 (用于方法调用)
【发布时间】:2012-03-16 02:10:14
【问题描述】:

我想知道是否可以进行三元运算但不返回任何内容。

如果在 Java 中不可能,那么在其他语言中是否可能,如果可以,哪些适用?

name.isChecked() ? name.setChecked(true):name.setChecked(false);

【问题讨论】:

标签: java methods boolean return ternary


【解决方案1】:

有时,您可以对方法参数使用三元运算来解决您的请求。

name.setChecked(name.isChecked() ? true : false);

顺便说一句,解决您的问题的最佳方法是

name.setChecked(name.isChecked());

【讨论】:

    【解决方案2】:

    我假设问题中的用例只是一个糟糕的例子,因为它等同于以下语句:

    name.setChecked(name.isChecked());
    

    ...这也没有意义。但是意图很明确,确实有很多相关的用例。

    唯一可行且通用的解决方案是添加这样的辅助方法:

    static void ternaryVoid(boolean condition, Runnable ifTrue, Runnable ifFalse) {
        (condition ? ifTrue : ifFalse).run();
    }
    

    并像这样使用它:

    ternaryVoid(name.isChecked(), () -> name.setChecked(true), () -> name.setChecked(false));
    

    但它失去了三元运算符的优雅,只有在代码的多个部分使用并且纳秒无关紧要时才值得“努力”。

    但这与 if-else 语句相比有什么意义呢?你真的要保存 7 个字符吗?

    我很惊讶这样的陈述以反问的形式出现。是的,节省 4 行代码并使代码更优雅很重要,尤其是在函数式编程的上下文中。

    此外,void 方法是否返回完整的Void 至少是有争议的。本质上,它们返回完成任务的通知。这就是为什么从逻辑上讲,三元表达式无论返回什么或什么都不返回都同样有意义:

    condition ? doThis() : doThat();
    

    下面是一个类的真实世界示例,它每秒可以处理数百万次增量更新:

    public class DataHandler {
    
        private final TreeMap<Integer, Long> tree = new TreeMap<>();
    
        public void onUpdate(int price, long amount) {
            if (amount == 0) {
                tree.remove(price);
            } else {
                tree.put(price, amount);
            }
        }
    }
    

    如果允许,onUpdate() 方法将是一个不错的三元表达式,如下所示:

    public void onUpdate(int price, long amount) {
        (amount == 0) ? tree.remove(price) : tree.put(price, amount); // compilation error
    }
    

    幸运的是,在某些情况下,两个目标方法都返回值,并且这些值属于同一类型,在这种情况下为Long。这允许使onUpdate 方法在price 返回以前的amount(这甚至很有用)

    public Long onUpdate(int price, long amount) {
        return (amount == 0) ? tree.remove(price) : tree.put(price, amount);
    }
    

    ...或者(例如,如果方法由接口确定),使用虚拟变量并抑制其无用警告:

    public void onUpdate(int price, long amount) {
        @SuppressWarnings("unused")
        Long dummy = (amount == 0) ? tree.remove(price) : tree.put(price, amount);
    }
    

    否则,这些解决方案不适用,并且正如其他人所回答的那样,不存在。例如,可以尝试以下方法:

    Consumer<Void> dummy = (x) -> {};
    dummy.accept(/*...*/);
    

    但有趣的是,第二行编译时既没有任何东西也没有任何东西作为参数。

    似乎最好的通用解决方案是上面的辅助方法ternaryVoid()

    【讨论】:

      【解决方案3】:

      在java中下面的代码是不可能的:

      (your-condition) ? (true-statements) : (false-statements)
      

      对于示例,您无法编译以下片段代码:

      (1==1) ? System.out.println("") : System.out.println("");
      

      你实现了以下编译错误:

      The left-hand side of an assignment must be a variable
      

      【讨论】:

      • (your-condition) ? (true-statements) : (false-statements) 在 java 中是可能的,但它必须返回一个值(它不能是 void)并且你必须将它分配给一个变量。
      【解决方案4】:

      您必须返回一些值,如果您希望它像 void 方法一样执行某些操作而不返回值,它将无法工作。

      希望这会有所帮助...

      【讨论】:

      【解决方案5】:

      我想知道是否可以进行三元运算但不返回任何内容。

      不,这是不可能的:

      1. 第二和第三个操作数必须是非空表达式;即它们必须产生一些实际价值。

        “第二个或第三个操作数表达式调用 void 方法是一个编译时错误。” - JLS 15.25

      2. 三元表达式是表达式,不能用作语句。

        “某些类型的表达式可以用分号作为语句。” ...而三元表达式不是其中之一 - JLS 14.8

      如果你真的,真的想使用三元表达式但不使用表达式的值,那么最简单的方法是将值分配给一个虚拟变量,并添加注释以抑制关于变量不存在的警告用过。

      但更好的办法是使用简单的if 语句。

      如果在 Java 中不可能,那么在其他语言中是否可能,如果可以,哪些适用?

      我有点生疏,但我相信 C、C++ 和 Perl 都允许在不使用其值的地方使用任意表达式。

      【讨论】:

        【解决方案6】:

        不,你不能。但是,if-else 声明的意义何在?您真的要保存 7 个字符吗?

        if (name.isChecked()) {
            name.setChecked(true);
        } else {
            name.setChecked(false);
        }
        

        或者如果你喜欢糟糕的风格:

        if (name.isChecked()) name.setChecked(true); else name.setChecked(false);
        

        别介意你可以做(​​在这种情况下):

        name.setChecked(name.isChecked());
        

        三元或“条件”运算符的重点是将条件引入表达式。换句话说,这是:

        int max = a > b ? a : b;
        

        是这个的简写:

        int max;
        if ( a > b ) {
            max = a;
        } else {
            max = b;
        }
        

        如果没有产生值,则条件运算符不是快捷方式。

        【讨论】:

        • 使用 Stream.forEach lambda 在我看来,在某些情况下,编写 (item -> item.isA() ? doA() : doB()) 会比使用大括号和扩展更优雅如果/否则。
        猜你喜欢
        • 2013-06-29
        • 2021-12-30
        • 2023-03-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-11
        相关资源
        最近更新 更多