java synchronization block multiple condition check - java

I have the following code
public class MyClass {
private boolean condition1;
private boolean condition2;
private boolean condition3;
public void start(){
synchronized (this) {
while(true){
if(!condition1 || !condition2 || !condition3) break;
.....//line #1
if(!condition1 || !condition2 || !condition3) break;
.....//line #2
if(!condition1 || !condition2 || !condition3) break;
.....//line #n
}
}
}
}
condition1 to 3 can be mutated by other objects. What I want to achieve is to break out of the looping immediately when any other object has set any of the condition to false. Surely there's a better way than putting one-liner if check before each line's execution?
Thanks

Well actually in genereal there is not. From common sence it is not unreasonable make such checks only in long running blocks inside your loop, i.e. not after each command.
As minumum I suggest you fix some compile-time errros, say !condition1 will not compile, as it is not boolean type. It should be !condition.get().
Next it inevitably comes to mind create check method: boolean test() { return !condition1.get() || ... ; } and use it in if (test()) break; instead of copying long if(!condition1.get() || ...) line multiple times.

while(!condition1 || !condition2 || !condition3) {
}
should do it, no?
better to combine the condition check into a separate method tho, as #Andremonly suggested.
If your conditions can be updated by other threads, they should be marked volatile when you declare them.

Related

Is there a better way to write this if statements?

I started recently as a developer and I am still struggling a bit with the way I write my code.
Is there a better way to write this two if-statements? How would you write it and why?
Java code:
#Override
#Transactional
public void deleteItem(final ConfigurationType type, final long itemId, final boolean force) {
this.applicationNameUtils.throwOnInvalidApplication(type.getApplication());
final ConfigurationItemModel item =
this.configurationItemRepository.findByApplicationAndTopicAndId(type.getApplication(), type.getTopic(), itemId)
.orElseThrow(() -> new ResourceNotFoundException(itemId, "Configuration Item"));
if (Boolean.TRUE.equals(item.getContentModificationOnly()) && Boolean.FALSE.equals(force)) {
throw new ContentModificationOnlyException("Configuration Item cannot be deleted");
}
if ((Boolean.TRUE.equals(item.getContentModificationOnly()) || Boolean.FALSE.equals(item.getContentModificationOnly())) && Boolean.TRUE.equals(force)) {
this.assignmentService.deleteAssignmentsByItem(item);
this.configurationInstanceRepository.deleteByItem(item);
this.configurationItemRepository.deleteById(itemId);
}
}
I am not sure if I can somehow combine this two in a if-else.
It looks like you don't care about item.getContentModificationOnly() is true or false in the second if-statement since your code is (Boolean.TRUE.equals(item.getContentModificationOnly()) || Boolean.FALSE.equals(item.getContentModificationOnly()). So if your logic is right I suggest you code like this:
if (fore) {
this.assignmentService.deleteAssignmentsByItem(item);
this.configurationInstanceRepository.deleteByItem(item);
this.configurationItemRepository.deleteById(itemId);
} else if (Boolean.TRUE.equals(item.getContentModificationOnly()) {
throw new ContentModificationOnlyException("Configuration Item cannot be deleted");
}
First if condition
if (item.getContentModificationOnly() && !force) {
Second If condition
if ((item.getContentModificationOnly() || !item.getContentModificationOnly()) && force) {
The below code will always return true
(item.getContentModificationOnly() || !item.getContentModificationOnly())
so modify second if stmnt to just
if (force){
Depends on the return type item.getContentModificationOnly(). If it's Boolean, than the second statement can be reduced to
if(item.getContentModificationOnly() != null && force)
If the return type of item.getContentModificationOnly() is boolean, than the statement can be reduced to
if(force)
and the answer of #LiLittleCat above if correct.

Reducing conditional operators efficiently

What I am trying to perform: I am trying to reduce the conditional operators, Since Sonar is giving a error for it
if (!parseBooleanFromString(response.getBuy().getHasEligibleAccounts()) &&
(!parseBooleanFromString(response.getSell().getHasEligibleAccounts()) &&
(!parseBooleanFromString(response.getExchange().getHasEligibleAccounts()) &&
(!parseBooleanFromString(response.getWorkplaceRetirement().getHasPlansEligibleForChangeContributions()) &&
(!parseBooleanFromString(response.getWorkplaceRetirement().getHasPlansEligibleForChangeInvestments())))))) {
//Success
} else {
//Failure
}
private boolean parseBooleanFromString(String mStr) {
return Boolean.parseBoolean(mStr);
}
What i have tried:
I am trying to put all the boolean values in a list and check
Is that the best way to do or is there a more efficient way
You can also move these conditions into different functions which internally calls other functions and returns single boolean result. This way there will only one function in above if condition which will internally evaluate and returns result.
Since you're checking if each statement is false, how about you keep a global integer in memory: private int product = 1;. Make a separate method where you calculate the product (replaces the string to boolean parser):
private void updateProduct(String mStr){
if (Boolean.parseBoolean(mStr)) //If true, condition should fail
product *= 0;
else
product *= 1;
}
In essence, you are not running 'if statement' but multiplying the boolean:
product = 1;
updateProduct(response.getBuy().getHasEligibleAccounts());
updateProduct(response.getSell().getHasEligibleAccounts());
//etc
if (product > 0){
//success
} else {
//failure
}
Explanation: If at any point a condition was true, the product will always be 0. The only instance where the product is > 0 is when all statements were false
Not sure what sonar complains about, but you have alot of redundant parenthesis and confusing negations. Using DeMorgans law, you can at least simplify to:
boolean b = parseBooleanFromString(response.getBuy().getHasEligibleAccounts())
|| parseBooleanFromString(response.getSell().getHasEligibleAccounts())
|| parseBooleanFromString(response.getExchange().getHasEligibleAccounts())
|| parseBooleanFromString(response.getWorkplaceRetirement().getHasPlansEligibleForChangeContributions())
|| parseBooleanFromString(
response.getWorkplaceRetirement().getHasPlansEligibleForChangeContributions());
if (!b) {
or if you perfer more java 8 syntax
Stream<Boolean> bools = Stream.of(parseBooleanFromString(response.getBuy().getHasEligibleAccounts()),
parseBooleanFromString(response.getSell().getHasEligibleAccounts()),
parseBooleanFromString(response.getExchange().getHasEligibleAccounts()),
parseBooleanFromString(response.getWorkplaceRetirement().getHasPlansEligibleForChangeContributions()),
parseBooleanFromString(response.getWorkplaceRetirement().getHasPlansEligibleForChangeContributions()));
boolean c = ! bools.anyMatch(e -> e);
if (!c) {
I would do something like this:
private boolean checkEligibility(LaunchPoints response) {
final String trueStr = "true";
if (trueStr.equals(response.getBuy().getHasEligibleAccounts())) return true;
if (trueStr.equals(response.getSell().getHasEligibleAccounts())) return true;
[...]
return false;
}
The idea is, skip the parsing boolean, just check for "true" and make your conditions more readable.

Is it possible to to declare variables within a condition?

This is how I would do a while loop:
boolean more = true;
while (more)
{
// do something
if (someTest())
{
more = false;
}
}
That's pretty standard. I'm curious to know if there's a way of doing something similar to the code below in Java: (I think I've seen something like it in C)
// The code below doesn't compile (obviously)
while (boolean more = true)
{
// do something
if (someTest())
{
more = false;
}
}
I only ask this because currently I don't like the way I'm defining the variable used in the condition (in this case: "more") outside the scope of the loop, even though it's only relevant inside the loop. There's no point it being left hanging around after the loop has finished.
* * Update * *
An idea came to me following a visit to the Porcaline Chamber of Secrets:
for (boolean more=true; more; more=someTest())
{
// do something
}
It's not perfect; It's abusing the for loop and I can't think of a way to execute the loop at least once, but it's close... Is there a way to make sure the loop is performed 1+ times?
To answer your question literally, you can do
for(boolean more = true; more; ) {
more = !someTest();
}
but this is much the same as
while(!someTest());
If it must execute at least once you can do
do {
} while(!someTest());
For your specific case, you can reduce your code to this:
while (true) {
if (someTest()) {
break;
}
}
In general, you could replace your outer-scope declaration with an inner-scope one, but you'd need to move the loop condition:
while (true) {
boolean more=true;
...
if (someTest()) {
more = false;
}
...
if (!more) {
break;
}
}
Or even:
do {
boolean more=true;
...
if (someTest()) {
more = false;
}
...
if (!more) {
break;
}
} while (true);
I'd opine that defining your condition outside the loop is clearer.
KidTempo, in the example you gave, I think that more would be re-initialized each time through the loop. Each time through the loop, the conditional is re-evaluated, so assuming that you are able to define a variable in a conditional, the variable would be re-initialized each time that conditional is re-evaluated. This would also apply to other types of conditionals, so I would say to avoid defining variables in a conditional.

Better way to structure/new keyword

Some time ago I came across the following construct which I have rarely seen since, though I use it relatively frequently. I use it typically when checking on a whole list of conditions are true and it prevents large levels of indentation. Essentially it uses a for loop to provide a kind of structured goto. My question is firstly whether there is better way to structure this, secondly whether people like it and thirdly whether a new keyword in java/c++ etc. such as unit { } which would only cause breaks to exit to the end of the unit would be useful and clearer.
ps I realise that it is on slip away from an infinite loop, but I think my paranoia about that has meant its never happened.
Edit: I have added some setup code for the further conditions to try to illuminate problems with chained if then elses
boolean valid = false;
// this loop never loops
for (;;)
{
if (!condition1)
break;
condition2.setup();
if (!condition2)
break;
condition3.setup();
if (!condition3)
break;
valid = true;
break;
}
if (valid) dosomething();
EDIT:
I have just discovered that in fact there is a way to structure this in java without misusing loops etc. and wondered whether this would similarily be frowned on, though I guess I have missed the boat on this one.
The restructured code looks like this.
boolean valid = false;
breakout:
{
if (!condition1)
break breakout;
condition2.setup();
if (!condition2)
break breakout;
condition3.setup();
if (!condition3)
break breakout;
valid = true;
}
if (valid) dosomething();
Now that removes the misuse of the for loop which caused a lot of the complaints, and is actually a solution I think is quite neat and is what I was looking to find originally.
I am guessing that this structure is probably not well known since no one mentioned it, people object to this as strongly?
The loop is counter-intuitive and would be questioned at code review: "Why do you need a loop if you always break on the first iteration?"
Why not use this?
boolean valid = true;
if (!condition1)
valid = false;
else if (!condition2)
valid = false;
else if (!condition3)
valid = false;
if (valid) dosomething();
You may have heard of these things modern programming languages have, called functions ;)
One of the key reasons goto is no longer used is that we can now factor code out into separate functions, and call them instead.
One way to solve your problem would be to put the code in a separate function instead, and return instead of breaking from your pseudo-loop:
void safedosomething() {
if (!condition1)
return;
condition2.setup();
if (!condition2)
return;
condition3.setup();
if (!condition3)
return;
dosomething();
}
or write helper functions (such as bool checkcondition1() { condition1.setup(); return condition1; }) which set up and then test the conditions, and use a boolean flag:
bool valid = true;
if (!checkcondition1())
valid = false;
if (!checkcondition2())
valid = false;
if (!checkcondition3())
valid = false;
if (!checkcondition4())
valid = false;
if (valid) dosomething();
or a bit more concisely:
bool valid = true;
valid &&= checkcondition1();
valid &&= checkcondition2();
valid &&= checkcondition3();
valid &&= checkcondition4();
if (valid) dosomething();
or just
if (checkcondition1()
&& checkcondition2()
&& checkcondition3()
&& checkcondition4())
dosomething();
There are plenty of ways to express this, without counterintuitive loops-that-don't-loop.
The reason for this construct is because goto is a dirty word in programming. But lets face it, you are effectively using the loop construct to do the same thing. My opinion on this is either be honest and use the goto or refactor the code.
I don't think it's the most readable way of doing it. Chained if-else if looks much better. But if you want to stick with it and don't want to be so close to an infinite loop, you could do something like this:
do
{
if (...)
break;
...
} while (false);
C++ only, unfortunately:
if ( condition1
&& (condition2.setup(), condition2)
&& (condition3.setup(), condition3) )
{
dosomething();
}
For something java compatible (but I'm still writing C++!) I would fall back to something along the lines of this. (Obviously, some context may need to be passed into CheckConditions().)
bool CheckConditions()
{
if (!condition1)
return false;
condition2.setup();
if (!condition2)
return false;
condition3.setup();
if (!condition3)
return false;
return true;
}
//...
if (CheckConditions())
{
dosomething();
}
//...
You seem concerned that evaluating condition 2 requires some setup, and you don't know where to put it. Refactor that into a separate boolean method and then use that the way almost everybody here has described. For example:
if (checkCondition1() && checkCondition2(someInput) && checkCondition3()) {
doSomething();
}
and..
private boolean checkCondition2(Object someInput) {
//setup condition 2
return condition2;
}
I think the problem with
if (condition1 && condition2 && ...)
was simply that it could become hard to read and edit if there are lots of conditions, although you could always write it like this:
if ( condition1 &&
condition2 &&
condition3 ... )
doStuff();
How about you turn the loop into a function:
bool all()
{
if (!condition1) return false;
if (!condition2) return false;
if (!condition3) return false;
....
return true;
}
Here's sort of compromise, if you want to keep the indentation as it is:
boolean valid = true; // optimistic start
if (!valid || !condition1)
valid = false;
if (!valid || !condition2)
valid = false;
if (!valid || !condition3)
valid = false;
if (valid)
doSomething();
The !valid in the first if statement is superflucious but doesn't harm, could be kept for readability. else/if is more elegant, to my opinion, but that's just an opinion.
But I really wouldn't (ab-)use the for loop and I never ever would find a cheap way to implement a pseudo-goto. There's always a better solution.
I'm not sure why you need a loop if there is a break statement at the end of the loop. Arent you just iterating once, no matter the situation?
Anyway, you'll usually find two differing opinions concerning this on SO, one being that break statements shouldn't be used at all, and one being that it depends on the situation.
I tend to fall in with the latter group, but the way that your loop works uses superfluous break statements. I'd much rather structure such a loop like this:
bool valid = true;
for(... ; .... && valid == true ; ....)
{
if (!condition1)
valid = false;
if (!condition2)
valid = false;
if (!condition3)
valid = false;
}
This allows a loop exit that I think is more elegant.
Having such a long if statement is most likely bad coding.
It makes it very hard to test, and is most likely a code smell.
If possible you should refactor to take advantage of polymorphism.
How about relocating the setup to the operator bool on the Condition class? This makes it far more readable and hides the mechanics.
class Condition
{
bool _isSet;
public:
Condition() : _isSet(false) {
}
void setup() {
_isSet = true;
}
operator bool () {
if (!_isSet) {
setup();
}
return rand() & 1;
}
};
void doSomething()
{
}
int _tmain(int argc, _TCHAR* argv[])
{
Condition cond1, cond2, cond3;
if (cond1 && cond2 && cond3) {
doSomething();
}
return 0;
}
You can take that code out to a separate function and use multiple return statements. You will likely need to refactor the long list of if statements into a separate function anyway.
bool isValid()
{
if (!condition1)
return false;
condition2.setup();
if (!condition2)
return false;
condition3.setup();
if (!condition3)
return false;
return true;
}
Then you could use it in your code:
if (isValid()) dosomething();

Is there any appreciable difference between if and if-else?

Given the following code snippets, is there any appreciable difference?
public boolean foo(int input) {
if(input > 10) {
doStuff();
return true;
}
if(input == 0) {
doOtherStuff();
return true;
}
return false;
}
vs.
public boolean foo(int input) {
if(input > 10) {
doStuff();
return true;
} else if(input == 0) {
doOtherStuff();
return true;
} else {
return false;
}
}
Or would the single exit principle be better here with this piece of code...
public boolean foo(int input) {
boolean toBeReturned = false;
if(input > 10) {
doStuff();
toBeReturned = true;
} else if(input == 0) {
doOtherStuff();
toBeReturned = true;
}
return toBeReturned;
}
Is there any perceptible performance difference? Do you feel one is more or less maintainable/readable than the others?
With the second example you state very clearly that both conditions are mutually exclusive.
With the first one, it is not so clear, and in the (unlikely) event that an assignment to input is added between both ifs, the logic would change.
Suppose someone in the future adds input = 0 before the second if.
Of course this is unlikely to happen, but if we are talking about maintainability here, if-else says clearly that there are mutually exclusive conditions, while a bunch of ifs don't, and they are not so dependent between each other as are if-else blocks.
edit:Now that I see, in this particular example, the return clause forces the mutual exclusivity, but again, we're talking about maintainability and readability.
Anyway, about performance, if this is coded in Java you shouldn't care for performance of a couple of if blocks, if it were embedded C in a really slow hardware, maybe, but certainly not with java.
Use whatever form best describes your intent.
Do not follow the single exit principle if things are this simple, though--it just makes it more confusing.
In the first:
somebody eventually, by some strange reason and when you're not looking will add some add statement that will make this method fail under certain strange conditions, everybody ( or worst, one single person ) will spend 4 hrs. watching the source code and debugging the application to finally found there was something in the middle.
The second is definitely better, not only it prevents this scenario, but also helps to clearly state , it this or this other no more.
If all the code we write within an if where 10 lines long at most, this wouldn't matter really, but unfortunately that's not the case, there exists other programmers which by some reason think that a if body should be > 200 lines long... anyway.
I don't like the third, it forces me to look for the return variable, and it's easier to find the return keyword
About speed performance, they are ( almost ) identical. Don't worry about that.
In your last example, don't do this:
public boolean foo(int input) {
boolean toBeReturned = false;
if(input > 10) {
doStuff();
toBeReturned = true;
} else if(input == 0) {
doOtherStuff();
toBeReturned = true;
}
return toBeReturned;
}
but this (notice the use of Java's final):
public boolean foo(int input) {
final boolean toBeReturned; // no init here
if(input > 10) {
doStuff();
toBeReturned = true;
} else if(input == 0) {
doOtherStuff();
toBeReturned = true;
} else {
toBeReturned = false;
}
return toBeReturned;
}
By doing so you make your intend clear and this is a godsend for IDEs supporting "programming by intention" (there's no need to "compile" to see potential errors, even on a partial AST, a good IDE can examine incomplete source in real-time and give you instant warnings).
This way you are sure not to forget to initialize your return value. This is great if later on you decide that after all you need another condition.
I do this all the time and even moreso since I started using IntelliJ IDEA (version 4 or so, a long time ago) and this has saved me so many silly distraction mistakes...
Some people will argue that this is too much code for such a simple case but that's entirely missing the point: the point is to make the intent clear so that the code reads easily and can be easily extended later on, without accidentally forgetting to assign toBeReturned and without accidentally forgetting to return from a later clause you may add.
Otherwise, if "conciseness" was the name of the game, then I'd write:
public boolean foo(int a) {
return a > 10 ? doStuff() : a == 0 ? doOtherStuff() : false;
}
Where both doStuff and doOtherStuff would return true.
Semantically — no. Performance-wise this depends on compiler, i.e. whether it can spot that both conditions cannot be true at once. I'd bet standard Sun compiler can. Whether to use single exit principle depends on tastes. I personally hate it.
Version #1 and #2 may be faster than #3, but I suppose the performance difference is minimal. I would rather focus on readability.
Personally, I would never use version #2. Between #1 and #3, I would choose the one that yields the most readable code for the case in question. I don't like many exit points in my methods, because it makes the code hard to analyze. However, there are cases where the flow becomes clearer when we exit immediately for some special cases, and continue with the main cases.
Think of this case when the two examples won't be similar:
public boolean foo(int input) {
if (input > 10) {
// doStuff();
return true;
}
System.out.println("do some other intermediary stuff");
if (input == 0) {
// doOtherStuff();
return true;
}
return false;
}
vs.
public boolean foo(int input) {
if (input > 10) {
// doStuff();
return true;
}
//System.out.println("doing some intermediary stuff... doesn't work");
else if (input == 0) {
// doOtherStuff();
return true;
} else {
return false;
}
return false;
}
The first approach is probably more flexible, but both formulas have their use in different circumstances.
Regarding performance, I think the differences are to small to be taken in consideration, for any regular java application, coded by sane programmers :).
In your case the second if would only get called if the first if failed so it's less important here but if your first if did something and didn't return, the second if (which would then always be false) would still be tested unless it was in an else-if.
In other words, there are cases where the difference between if-else-if and if-if matters, but this isn't one of them.
Example: Try this and then try it after removing the else. You get two different outputs:
int someNumber = 1;
if(someNumber < 5)
{
someNumber += 5;
Console.WriteLine("First call.");
}
else if(someNumber >= 5)
{
Console.WriteLine("Second call.");
}
Between the first and second snippets, there's really no difference. However the third snippet is quite inefficient. Because you wait to return control of the program to the caller until the last line of code in the method, you waste processing power/memory whereas the first two code snippets return control as soon as it determines one of the conditions to be true.

Categories