Is there a better way to write this if statements? - java

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.

Related

Convert nested loops into a Stream

I want to replace nested for loops in the following code with streams:
private boolean check(St st) {
List<Co> prereqs = getCoPrereqs();
for (Co prereq : prereqs) {
List<En> stEns = st.getEns();
boolean flag = false;
for (En en : stEns) {
if (en.getCo().equals(prereq) && en.getGr() != null) {
if (en.hasPassedCo()) {
flag = true;
}
}
if (!flag)
return false;
}
}
return true;
}
The two loops and the variable flag is causing confusion. I am not sure if this can be converted to streams totally.
I have simplified your code somewhat by doing the following:
removing the boolean flag. It isn't necessary.
get the List<En> just one time outside of the Prereq loop. You can reiterate the original as often as necessary.
The major difference is to check for a false return from en.hasPassedCo() and return false immediately. Once the iterations are complete, then return true.
private boolean check(St st) {
List<Co> prereqs = getCoPrereqs();
List<En> stEns = st.getEns();
for (Co prereq : prereqs) {
for (En en : stEns) {
if (en.getCo().equals(prereq) && en.getGr() != null) {
if (!en.hasPassedCo()) {
return false;
}
}
}
}
return true;
}
I'm not certain that streams would improve this (at least not knowing more about the relationships of the fields to each other). Also, it doesn't make sense how Co relates to en.getCo. Seems to me that something like prereqs.contains(en.getCo()) would be more appropriate.
Probably, you can use nested streams with allMatch.
I'm saying "probably" because I can't be sure that the code you've proved does what expected, types name are not self-explanatory at all (names in the code matter a lot) and you have not accompanied the code with any explanations.
If I understood your code correctly, you need to validate every Co object returned by getCoPrereqs() and that entails checking each Co object against En object from a List<En> which should be extracted from the method parameter.
That's how it might look like:
private boolean check(St st){
return getCoPrereqs().stream()
.allMatch((Co prereq) -> st.getEns().stream()
.allMatch((En en) -> en.getCo().equals(prereq)
&& en.getGr() != null
&& en.hasPassedCo()
));
}
For readability reasons (to make it more easier to compare stream with loops), I've used explicitly typed lambda expressions (the common practice is to omit types for brevity and let the type inference do the job).

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.

Better way of returning from condition

Which way of returning from condition is better , Like the process1 and process 2 both does the same. But I want to know better way returning.
In both cases I don't want to enter inside of loop, I just want to return. I would like to know that, Is there any performance difference If I put return before control passes to end. I don't want Java Virtual Machine to check end of loop and returning from there. I thought If I put return Immediately when the condition not satisfied, then I could see minor performance difference and also code readability. Please suggest me the best way.
Let us consider the below scenarios.
Process1:
public Method()
{ //Method
Company company = new Company(); //Object
if (null != Address && null = Address.location()) //Condition
{
return company; //I want to return
}
for (Location location: Address.location())
{
//forloop
}
return company; //return
}
Process2:
public Method()
{
Company company = new Company();
if (null != Address && null != Address.location())
{
//enters loop
}
return company; // return
}
There will be some performance impact. Iterating complete objects from the for loop to verify the condition.
For example:
We can write like this.
if(condition is false){
return ;
else{
for(DataType ref: collection){
if(true){
return;// return from here, so that it will not iterate remaining elements.
}
}
}
ex 2:
if there is a logic after the if and that should not be executed, if the object is null.
if(object is null){
return ;
}
//Remaining logic here will not be executed, if the object is null. it's a good way of writing.
ex 3:
if there is no logic after the if and else, then directly return from the end of method.
if(object is null){
return
}else{
//process logic and return.
}
you can write something like this.
if(object is not null){
// return either from here.
}
return here is also fine...

Do I have this written properly? .equals AND !.equals if statement

FIXED. To get the statement to evaluate the way I wanted it to I had to write it this way:
public static Boolean pushCard(String S1, String S2) {
Boolean result = false;
if ((S1.equals("fire") || S1.equals("wind") || S1.equals("water")))
if (!S2.equals("fire") && (!S2.equals("water") && (!S2.equals("fire"))))
result = true;
return result;
} //end push card method
I can not tell if this comparison is causing issues. I was using == instead of .equals but then I learned that it was the wrong way to write it. Thanks for the help!
public static Boolean pushCard(String S1, String S2) {
Boolean result = false;
if ((S1.equals("fire") || S1.equals("wind") || S1.equals("water")))
if (!S2.equals("fire") || (!S2.equals("water") || (!S2.equals("fire"))))
result = true;
return result;
} //end push card method
Syntactically, your code will compile just fine, and the way you use .equals() method to compare strings is correct. Your use of the ! operator is also correct.
There is no guarantee that your code will not have logical errors though.
The only problem I can see you have "fire" mentioned twice in your second if statement. Otherwise, any problems you might be having could be related to your logic being wrong, since your syntax is pretty much correct and your usage is proper.
It is unclear what you're asking. The second if will always be true. You probably need :
if ((S1.equals("fire") || S1.equals("wind") || S1.equals("water")))
if (!S2.equals("fire") && (!S2.equals("water") && (!S2.equals("wind"))))
result = true;
public static Boolean pushCard(String S1, String S2)
{
Boolean result = false;
if (S1.equals("fire") || S1.equals("wind") || S1.equals("water"))
{
(!S2.equals("fire") || !S2.equals("water"))
result = true;
}
return result;
}
/end push card method
you had an extra pair of brackets in the first if statement.
I believe an if statement needs brackets {} when the code inside it is larger than one line.
your second if statement can be altered to just !S2.equals("fire") || !S2.equals("water")

How avoid multiple IF loops in Java [duplicate]

This question already has answers here:
Avoiding NullPointerException in Java
(66 answers)
Closed 9 years ago.
What is the best way to avoid multiple if blocks which is used for null checks in Java?
The following is my sample code. Which one is the most optimized way?
if (address!=null} {
if (firstName!=null) {
if (lastName!=null) {
}
}
}
Use &&. && is logical and. && combines two values and returns a boolean which is true if and only if both of its operands are true
if(address!=null && firstName!=null && lastName!=null)
{
}
For instance
boolean b;
b = 3 > 2 && 5 < 7; // b is true
b = 2 > 3 && 5 < 7; // b is now false
if loop is a wrong word. You should say if statements As in you case you can use OR (||) or AND (&&)statement like this
if(address!=null && firstName!=null && lastName!=null)
{
}
Try AND(&&) if you want to pass all checks or intead of nested if statements and try OR(||) for non nested like else if or simply say if you want to pass anyone of your condition But
if all of these are Strings then you should try like this
"yourValue".equals(stringValue)This will skip the null check.
Use and operator (&&)
if(address!=null && firstName!=null && lastName!=null)
{
//DoSomething here
}
And I suggest you to see Short circuit evaluation
there are no if LOOPS
boolean complete = address != null && firstName != null && lastName != null;
if (complete)
{
}
What about:
public boolean notNulls(Object ... args) {
for(Object arg : args)
if (arg == null) return false;
return true;
}
Use:
if (notNulls(address, firstName, lastName)) {
// do something
}
As others point out, a logical and (&&) is probably the best way to consolidate your logic. An && operation will only evaluate to true if both sides evaluate to true.
if (address != null && firstName != null && lastName != null) {
// Whatever you want to do with that...
} else {
// Whatever you want to do with bad input
}
For the sake of diversity, you could also use a try-catch approach. In Java, a NullPointerException will be thrown if you try to call a method on a null value, which you can catch and handle.
try {
// Whatever you want to do with that...
} catch (NullPointerException npe) {
// Whatever you want to do with bad input
}
This approach can be helpful if you've got a really big set of inputs that might be null, although in general I wouldn't advocate it. (The problem with the second approach is that if you call some other method from the try part that triggers a NullPointerException, it will end up in the catch block here, even though it may be totally unrelated to these inputs - i.e. you could make it hard for yourself to spot a bug in a different part of your program.)

Categories