简体   繁体   English

自动更新布尔值

[英]Automatically updating boolean value

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

Full Code: http://pastebin.com/UghV3xdT 完整代码: http//pastebin.com/Ug​​hV3xdT

I have 2 practically identical methods that can only different by one if-statement: if (k % 3 != 1) and if(k % 2 == 0) . 我有两个几乎相同的方法,只能用一个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++;
    }
}

The use of each cases is determined by the length of an Array which means the specific case only has to be determined 1 time. 每种情况的使用由阵列的长度决定,这意味着特定情况只需要确定一次。 'k' represents the index of another array and 50 is the length of this Array. 'k'表示另一个数组的索引,50表示此Array的长度。

I could write something like if(foo > 1 ? k % 3 != 1 : k % 2 == 0) but that requires the program to do the action every time the loop runs. 我可以编写类似if(foo > 1 ? k % 3 != 1 : k % 2 == 0)但这需要程序在每次循环运行时执行操作。

In a way I would like a sort of updating boolean. 在某种程度上,我想要一种更新布尔值。 Is there any way to do this, or is this the downside of pass-by-value? 有没有办法做到这一点,或者这是传值的缺点? Should I keep two seperate methods or am I better of with using the ternary operator? 我应该保留两种单独的方法,还是使用三元运算符?

In essence I'm looking for a type that contains the expression rather than the value. 本质上,我正在寻找一个包含表达式而不是值的类型。

In Java 8 there is nice functional interface called IntPredicate . 在Java 8中,有一个很好的功能接口叫做IntPredicate If you combine it with lambda expressions, you can achieve your goal with no duplication, extra code or any slow downs: 如果将它与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: Please not that I use the random boolean value to switch between the predicates, but you can use whatever condition you have PS:请注意,我使用随机布尔值在谓词之间切换,但您可以使用任何条件

You can create two different classes that have the same function and then use one of it. 您可以创建两个具有相同功能的不同类,然后使用其中一个。 For example, out of the loop: 例如,在循环之外:

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());

Then you can use in the loop only x.calc(k) . 然后你只能在循环中使用x.calc(k)

I could not see any way to simplify the logic of your ternary expression in a clever way. 我看不出有什么方法可以巧妙地简化三元表达式的逻辑。 But if you place the logical check outside the while loop over k , then you will only have to make the check once: 但是如果你将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++;
    }
}

This isn't beautiful code, but it frees you from having to use a ternary expression in each iteration of the loop. 这不是很漂亮的代码,但它让你不必在循环的每次迭代中使用三元表达式。

Java 8 allows many variants: Java 8允许许多变体:

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

Or make a method and use ::businessLogic . 或者创建一个方法并使用::businessLogic

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

Purely a matter of taste, but I like to see the hard numeric constants together. 纯粹是品味问题,但我喜欢看到硬数字常数。 Of course one may write: 当然可以写:

To have a loop without condition for the test: 要有一个没有测试条件的循环:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM