简体   繁体   English

如何从Java中的循环中删除while(true)?

[英]How can I remove the while(true) from my loop in Java?

I've heard that using while(true) is a bad programming practice. 我听说使用while(true)是一种糟糕的编程习惯。

So, I've written the following code to get some numbers from a user (with default values). 所以,我编写了以下代码来从用户那里获取一些数字(默认值)。 However, if the user happens to type in -1, then it will quit the program for them. 但是,如果用户碰巧输入-1,那么它将退出程序。

How should this be written then without a while(true)? 如何在没有片刻(真实)的情况下写出来? I can think of a condition to make the while loop go off that will get caught right away without continuing on until the next iteration? 我可以想到一个条件让while循环关闭会立即被捕获而不会继续直到下一次迭代?

Here is how I have it now: 我现在就是这样的:

 public static void main(String[] args)
    {
        System.out.println("QuickSelect!");

        while (true)
        {
            System.out.println("Enter \"-1\" to quit.");

            int arraySize = 10;
            System.out.print("Enter the size of the array (10): ");
            String line = input.nextLine();
            if (line.matches("\\d+"))
            {
                arraySize = Integer.valueOf(line);
            }

            if (arraySize == -1) break;

            int k = 1;
            System.out.print("Enter the kth smallest element you desire (1): ");
            line = input.nextLine();
            if (line.matches("\\d+"))
            {
                k = Integer.valueOf(k);
            }

            if (k == -1) break;

            List<Integer> randomData = generateRandomData(arraySize, 1, 100);

            quickSelect(randomData, k);
        }
    }

while (true) is fine. while (true)很好。 Keep it. 收下。

If you had a more natural termination condition, I'd say to use it, but in this case, as the other answers prove, getting rid of while (true) makes the code harder to understand. 如果你有一个更自然的终止条件,我会说要使用它,但在这种情况下,正如其他答案证明的那样,摆脱while (true)会使代码更难理解。

There is a Single Entry Single Exit (SESE) school of thought that suggests that you should not use break , continue or abuse exceptions to do the same for some value of abuse). 有一个单一入口单一退出(SESE)的思想学派,建议你不要使用breakcontinue或滥用例外对某些滥用价值做同样的事情)。 I believe the idea here is not that you should use some auxiliary flag variable, but to clearly state the postcondition of the loop. 我相信这里的想法不是你应该使用一些辅助标志变量,而是要明确说明循环的后置条件。 This makes it tractable to formerly reason about the loop. 这使得以前推理循环变得易于理解。 Obviously use the stands-to-reason form of reasoning, so it is unpopular with the unwashed masses (such as myself). 显然使用从理论上说是理性的形式,所以它对未洗过的群众(比如我自己)不受欢迎。

public static void main(String[] args) {
    ...
    do {
        ...
        if (arraySize == -1)  {
            ...
            if (k != -1) {
                ...
            }
        }
    } while (arraySze == -1 || k == -1);
    ...
}

Real code would be more complex and you would naturally(!) separate out the inputing, outputting and core "business" logic, which would make it easier to see what is going on. 真正的代码会更复杂,您自然会(!)将输入,输出和核心“业务”逻辑分开,这样可以更容易地看到正在发生的事情。

    bool exit = false;
while (!exit) {
    ...
    ...
    if (k == -1) {
        exit = true;            
    }
    else {         
        List <Integer> ....;
        quickselect(.......);
    }
}

But as has been said before, your while loop is a valid usage in this situation. 但正如之前所说,在这种情况下,while循环是一种有效的用法。 The other options would simply build upon the if statements to check for the boolean and exit. 其他选项将简单地构建在if语句上以检查boolean和exit。

While having a loop like this is not technically wrong, some people will argue that it is not as readable as the following: 虽然这样的循环在技术上不是错误的,但有些人会认为它不像以下那样可读:

bool complete = false;

while (!complete)
{

    if (arraySize == -1)
    {
        complete = true;
        break;
    }
}

Additionally, it is sometimes a good idea to have a safety loop counter that checks to make sure the loop has not gone through, say, 100 million iterations, or some number much larger than you would expect for the loop body. 此外,有时候有一个安全循环计数器是一个好主意,它可以检查以确保循环没有经过,例如,1亿次迭代,或者比循环体预期的大一些数量。 This is a secure way of making sure bugs don't cause your program to 'hang'. 这是一种确保错误不会导致程序“挂起”的安全方法。 Instead, you can give the user a friendly "We're sorry but you've discovered a bug.. program will now quit.." where you set 'complete' to true and you end the program or do additional error handling. 相反,你可以给用户一个友好的“我们很抱歉,但你发现了一个错误..程序现在将退出..”你将'complete'设置为true并结束程序或执行其他错误处理。 I've seen this in production code, and may or may not be something you would use. 我在生产代码中看过这个,可能会也可能不会是你会使用的东西。

If you really don't like while(true) you can always go for for(;;) . 如果你真的不喜欢while(true)你可以随时for(;;) I prefer the latter because it seems less redundant. 我更喜欢后者,因为它似乎不那么多余。

while ( true ) is perfectly fine here, since the condition is really "while the user doesn't want to quit"! 而(true)在这里完全没问题,因为条件确实是“当用户不想退出”时!

Alternatively you could prompt for both the inputs on one line to simplify the logic, and use "q" for quit: this allows you to refactor the loop to "while ( !line.equals("q") )". 或者,您可以在一行上提示两个输入以简化逻辑,并使用“q”进行退出:这允许您将循环重构为“while(!line.equals(”q“))”。

The problem is that you're doing an awful lot in that loop, rather than separating the functionality into simple methods. 问题是你在这个循环中做了很多,而不是将功能分成简单的方法。

If you want to stick to a procedural approach, you could move the reading of the array size and k into separate methods, and use the fact that the result of an assignment is the assigned value: 如果要坚持使用过程方法,可以将数组大小和k的读取移动到单独的方法中,并使用赋值结果为赋值的事实:

    for (int arraySize; ( arraySize = readArraySize ( input ) ) != -1;) {
        final int k = readKthSmallestElement ( input );

        List<Integer> randomData = generateRandomData(arraySize, 1, 100);

        quickSelect(randomData, k);
    }

However that's still a bit ugly, and not well encapsulated. 然而,这仍然有点难看,并没有很好的封装。 So instead of having the two != -1 tests on separate variables, encapsulate arraySize , k and randomData in an object, and create a method which reads the data from the input, and returns either a QuickSelect object or null if the user quits: 因此,而不是具有两个!= -1在单独的变量测试,封装arraySizekrandomData中的对象,并创建其读取从输入的数据,并返回或者是一个方法QuickSelect对象或null如果用户退出:

    for ( QuickSelect select; ( select = readQuickSelect ( input ) ) != null; ) {
        select.generateRandomData();
        select.quickSelect();
    }        

You might even want to go to the next stage of creating a sequence of QuickSelect objects from the input, each of which encapsulate the data for one iteration: 您甚至可能希望进入从输入创建一系列QuickSelect对象的下一个阶段,每个阶段都封装一次迭代的数据:

    for ( QuickSelect select : new QuickSelectReader ( input ) ) {
        select.generateRandomData();
        select.quickSelect();
    }        

where QuickSelectReader implements Iterable and the iterator has the logic to create a QuickSelect object which encapsulates arraySize, k, the list and the quick select operation. 其中QuickSelectReader实现Iterable,迭代器具有创建QuickSelect对象的逻辑,该对象封装了arraySize,k,列表和快速选择操作。 But that ends up being quite a lot more code than the procedural variants. 但这最终会产生比程序变体更多的代码。

I'd only do that if I wanted to reuse it somewhere else; 如果我想在其他地方重复使用它,我只会这样做; it's not worth the effort just to make main() pretty. 仅仅为了使main()漂亮是不值得的。

Also note that "-1" doesn't match the regex "\\\\d+" , so you really do have an infinite loop. 还要注意"-1"与正则表达式"\\\\d+"不匹配,所以你确实有一个无限循环。

虽然(true){}在某些场景中非常有用..如果你说错误使用,你应该从1000层建筑中跳出来....

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

相关问题 如何停止Java循环吃掉> 50%的CPU? - How can I stop a Java while loop from eating >50% of my CPU? 我如何退出while循环? 基于我在Java中的预定义倒计时 - How can i exit from a while loop? Based on my pre-defined count down in Java 如何在 Java 中将我的代码从 while 循环更改为 do while 循环 - How would I change my code from a while loop to a do while loop in Java 我如何从 java 的收藏中删除项目 - how can i remove item from my collection in java 如何从Java代码中删除重复项? - How can I remove duplicated from my code in Java? 为什么我的 java while 循环继续以真实状态打印? - Why is my java while loop continue printing with true status? 我怎样才能让我的while循环只打印偶数? Java Eclipse 集成开发环境 - How can I make it so my while-loop only prints even numbers? Java Eclipse IDE 如何让我的 While 语句正确循环和中断,同时在 java 中输入另一个选项? - How can i get my While statement to correctly loop and break and at the same time input another option in java? 如何从 json output 中删除元素或属性,同时使用 xml - How can i remove an element or attribute from a json output while parsing from xml, using java 如何从 Java 中的 while 循环返回计数值 - How do i return the value of count from my while loop in Java
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM