自动更新布尔值

时间:2016-08-12 14:47:46

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

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

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

我有两个几乎相同的方法,只能用一个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++;
    }
}

每种情况的使用由数组的长度决定,这意味着特定情况只需要确定一次。 &#39; K&#39;表示另一个数组的索引,50表示此数组的长度。

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

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

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

4 个答案:

答案 0 :(得分:4)

在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:请注意,我不是使用随机布尔值来在谓词之间切换,但是你可以使用你拥有的任何条件

答案 1 :(得分:1)

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

h = pd.DataFrame(x.sum().values[np.newaxis,:].repeat(len(x.index), axis=0),
                 columns=x.columns,
                 index=x.index)

print (h)
    a   b
1  25  30
2  25  30
3  25  30
4  25  30
5  25  30


In [431]: %timeit df = pd.DataFrame([x.sum()] * len(x))
1000 loops, best of 3: 786 µs per loop

In [432]: %timeit (pd.DataFrame(np.tile(x.sum().values, (len(x.index),1)), columns=x.columns, index=x.index))
1000 loops, best of 3: 192 µs per loop

In [460]: %timeit pd.DataFrame(x.sum().values[np.newaxis,:].repeat(len(x.index), axis=0),columns=x.columns, index=x.index)
The slowest run took 8.65 times longer than the fastest. This could mean that an intermediate result is being cached.
10000 loops, best of 3: 184 µs per 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());

答案 2 :(得分:0)

我看不出有什么方法可以巧妙地简化三元表达式的逻辑。但是,如果您将逻辑检查放在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++;
    }
}

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

答案 3 :(得分:0)

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.