【问题标题】:Automatically updating boolean value自动更新布尔值
【发布时间】:2016-12-19 15:13:57
【问题描述】:

上下文: https://www.reddit.com/r/dailyprogrammer/comments/4wqzph/20160808_challenge_278_easymed_weave_insert_part_1/

完整代码: http://pastebin.com/UghV3xdT

我有 2 种几乎相同的方法,它们只能通过一个 if 语句来区分:if (k % 3 != 1)if(k % 2 == 0)

int k = 0;
while(k<50){
    if(k % 3 != 1){ // OR if(k % 2 == 0)
        // Code logic goes here
    k++;
    }
}

每种情况的使用由数组的长度决定,这意味着特定情况只需要确定一次。 'k' 表示另一个数组的索引,50 是这个数组的长度。

我可以写类似if(foo &gt; 1 ? k % 3 != 1 : k % 2 == 0) 的东西,但这需要程序在每次循环运行时执行该操作。

在某种程度上,我想要一种更新布尔值。有没有办法做到这一点,或者这是按值传递的缺点?我应该保留两个单独的方法还是使用三元运算符更好?

本质上,我正在寻找一种包含表达式而不是值的类型。

【问题讨论】:

    标签: java boolean pass-by-reference pass-by-value


    【解决方案1】:

    您可以创建两个具有相同功能的不同类,然后使用其中一个。例如,在循环外:

    class A{ bool calc(int n){return n%3 != 1} }
    class B{ bool calc(int n){return n%2 == 0} }
    Object x = (foo > 1 ? new A():new B());
    

    那么你只能在循环中使用x.calc(k)

    【讨论】:

    • 这和他原来用三元运算符的解法没什么区别
    • 这与原来的解决方案不同;注意这句话,“out of the loop。”这只是IntPredicate的pre-lambda版本。
    【解决方案2】:

    在 Java 8 中有一个很好的功能接口,称为IntPredicate。如果您将它与 lambda 表达式结合使用,您可以实现您的目标,而不会出现重复、额外代码或任何减速:

    public final class Example {
        public static void main(String[] args) {
            //Instead of randomly choosing the predicate, use your condition here
            Random random = new Random();
            IntPredicate intPredicate = random.nextBoolean() ? i -> i % 2 == 0 : i -> i % 3 != 1;
    
            int k = 0;
            while(k<50){
                /*
                 *At this point the predicate is either k%2==0 or k%3!=1,
                 * depending on which lambda you assigned earlier.
                 */
                if(intPredicate.test(k)){ 
                    // Code logic goes here
                    k++;
                }
            }
        }
    }
    

    PS:请不要我使用随机布尔值在谓词之间切换,但您可以使用任何条件

    【讨论】:

    • 假设 OP 可以并且想要使用 Java 8,这个答案很好。
    • 适用于java
    • 当然,假设 Java 8 是非常合理的。 Java 7 已经过时,Java 9 很快就会到来。
    • 这就是我要找的!谢谢!
    • @TomMartens 您好,如果您认为这是解决您问题的正确方法,请接受答案。
    【解决方案3】:

    我看不出有什么办法可以巧妙地简化三元表达式的逻辑。但是,如果您将逻辑检查放在 while 循环之外的 k 之外,那么您只需进行一次检查:

    int k = 0;
    
    if (foo > 1) {
        while (k < 50) {
            if (k % 3 != 1) {
                // code logic goes here
            }
            k++;
        }
    }
    else {
        while (k < 50) {
            if (k % 2 == 0) {
                // code logic goes here
            }
            k++;
        }
    }
    

    这不是漂亮的代码,但它使您不必在循环的每次迭代中使用三元表达式。

    【讨论】:

    【解决方案4】:

    Java 8 允许多种变体:

    IntConsumer businessLogic = (k) -> { ... };
    

    或者制作一个方法并使用::businessLogic

    if (foo) {
        IntStream.range(0, 50)
            .filter(k % 3 != 1)
            .forEach(businessLogic);
    } else {
        IntStream.range(0, 50)
            .filter(k % 2 == 0)
            .forEach(businessLogic);
    }
    

    纯属个人喜好,但我喜欢将硬数字常量放在一起。 当然可以写:

    要有一个没有条件的循环进行测试:

    IntStream is = IntStream.range(0, 50);
    is = ... ? is.filter(k % 3 != 1) : is.filter(k % 2 == 0);
    is.forEach(businessLogic); // Only now one iterates.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-22
      • 2017-04-30
      • 1970-01-01
      • 1970-01-01
      • 2017-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多