I have often heard that using break
s in Java is considered bad practice, but after reading some threads on Stack Overflow, I've seen otherwise. Many say that it is acceptable in certain cases.
I'm a little confused as to what is/isn't bad practice in this case.
For Project Euler: Problem 7, I've constructed the code below. The challenge was to find the 10001st prime.
int index = 2, count = 1, numPrime = 1;
while (true) {
index++;
if (isPrime(index)) {
count = index;
numPrime++;
}
if (numPrime >= 10001)
break;
}
System.out.println(count);
This returns the correct answer (in 21ms), but am I overlooking a serious warning? It's 100% possible to create a while loop without a break, but I find that this is a little easier to follow.
Is the way I use the break;
bad practice? I know that there's always a way around using one, but is it really that terrible here?
Many thanks
Justian
EDIT
Here's my isPrime() code. I might as well optimize this while I'm at it.
public static boolean isPrime(long num) {
if (num == 2)
return true;
if (num % 2 == 0 || num <= 0)
return false;
for (long i = 3; i * i <= num; i += 2)
if (num % i == 0)
return false;
return true;
}
(The examples given interest me. Typically, break and continue are disliked by people who like one entry and one exit from any piece of code, and that sort of person also frowns on multiple return statements.) I do not believe they are bad. The idea that they are bad comes from the days of structured programming.
Taking a break at work sometimes gets a negative perspective as managers think employees are slacking off or people want others to perceive that they are too busy to break away. Leaders and managers need to proactively encourage and take breaks themselves as examples for staff. It's ok for staff to see and know there are benefits in doing so.
Here’s a little insight on what happens when we start taking breaks at brief intervals - There is a limit to the amount of time for which human mind can remain focused. After that, it cannot remain as productive as it was when it was fresh. Breaks work as the triggers which deactivate your mind from the work. Once you come back it’s reactivated.
Generally speaking the conditions for your loops should be contained purely within those loop conditions not littered throughout the body. However there are some situations where break and continue can help readability. break moreso than continue I might add :D
I'm not sure that breaks in general are bad practice, but I think that this one is.
It's a bit silly because it's unnecessary. Your while (true) ... break
is entirely equivalent to:
while (numPrime < 10001) {
...
}
but much less intuitive.
Sticking with the canonical way to represent things means less computational overhead for your readers, makes your code easier to understand, thus easier to maintain and ultimately more robust.
Edit (in response to comment): You're right that there's always a way around using one, but the rule (if you want one) is relatively simple: write whatever is most readable. In the case you posted, this is not the most readable as the alternative I gave is the canonical way to represent this. In some cases, for example looping though a collection until you find a specific candidate that matches, using break
probably is the most fitting way to represent this pattern.
It would be difficult (and I woudl argue, futile) to try to come up with hard-and-fast rules about when to use break
and when to pull out variables and use conditionals instead. Often it's easy to tell what's the simplest option, but not always. This is one of those examples where experience really counts - the more good/bad code you've read and wrote yourself, the bigger your personal library of good and bad examples, and the easier it will be for you to tell what the "best"* way to represent a given concept is.
*Of course it's subjective!
In this case, it looks to me like it would be easier just to change the while
condition:
while (numPrime < 10001) {
That's usually the case when a while(true)
loop ends with
if (condition)
{
break;
}
... although you need to check whether anything else in the body of the loop performs a continue
.
Alternatively, you could restructure it slightly:
int current = 1;
for (int i = 0; i < 10001; i++)
{
current++;
while (!isPrime(current))
{
current++;
}
}
Then current
will be the answer at the end.
I generally prefer a for
loop over a while loop, when you're trying to do something a particular number of times. In this case the "something" is "find the next prime".
There are various bits of dogma in programming that I feel are taken too far - including "one exit point to a method" and "don't use break." Write code as readably as you can. If you look at some code and feel it's not blindingly obvious what's going on, try to work out other ways of structuring it. Sometimes that's a case of changing a loop; sometimes it's extracting a method; sometimes it's inverting some logic (deal with a negative branch first, possibly exiting early, and then handle the normal case).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With