I need to simplify following code in java. Are there any way to using set and do this ?
if (!(((AdministrativeState.PLANNED == dispensingOccasionModel.getOccasionDTO().getAdminState()) ||
(AdministrativeState.MISSED == dispensingOccasionModel.getOccasionDTO().getAdminState()) ||
(AdministrativeState.SKIPPED == dispensingOccasionModel.getOccasionDTO().getAdminState()) ||
(AdministrativeState.SELF_ADMINISTERED == dispensingOccasionModel.getOccasionDTO().getAdminState()) ||
(AdministrativeState.SELF_ADMINISTERED_BY_RANGE == dispensingOccasionModel.getOccasionDTO().getAdminState())) &&
isSpecialDoseType(doseDetail))
Using Set, you can initialize the valid enum types and perform a contains as #shmosel also pointed out in the comments :
Set<AdministrativeState> administrativeStates = Set.of(PLANNED, MISSED, SKIPPED, SELF_ADMINISTERED, SELF_ADMINISTERED_BY_RANGE)
if (!administrativeStates.contains(dispensingOccasionModel.getOccasionDTO().getAdminState())
|| !isSpecialDoseType(doseDetail))
It is unclear what data types are we dealing with here so I can't give you a better answer until you can shed more light on this. But assuming AdministrativeState is an enumerator you can do something like this:
public enum AdministrativeState {
NONE, PLANNED, MISSED, SKIPPED, SELF_ADMINISTERED,
SELF_ADMINISTERED_BY_RANGE;
}
public static class OccasionModel {
AdministrativeState state;
OccasionModel() {
this.state = AdministrativeState.NONE;
}
OccasionModel setState(AdministrativeState state) {
this.state = state;
}
}
public static void checkAdminState(OccasionModel model) {
OccasionModel dispensingOccasionModel = model;
if (dispensingOccasionModel.state != AdministrativeState.NONE) {
// Do something here...
}
else System.out.println("Administrative state is not set yet");
}
public static void main(String[] args) throws IOException {
checkAdminState(new OccasionModel());
checkAdminState(new OccasionModel().setState(AdministrativeState.PLANNED));
}
I am not sure if this is what you're looking for but this doesn't have anything to do with Java 8 in particular. If you can provide more information about what's what I can help you out further.
Provided the get methods have no side effects and return always the same value (within the scope of your sample),
you can use refactoring
Extract variable
s =dispensingOccasionModel.getOccasionDTO().getAdminState());
Also, you can statically import AdministrativeState.*.
You then get:
AdministrativeState s =dispensingOccasionModel.getOccasionDTO().getAdminState();
if (!(((PLANNED == s) || (MISSED == s ) || (SKIPPED == s) ||
(SELF_ADMINISTERED == s) ||
(SELF_ADMINISTERED_BY_RANGE == s))
&& isSpecialDoseType(doseDetail))
Then taking into account that the double pipe (Boolean OR) operator has quite a lot priority you can remove the parentheses around single comparisons:
(a==b)||(c==d) ===> a==b||c==d.
You get:
if (!((PLANNED == s ||
MISSED == s ||
SKIPPED == s ||
SELF_ADMINISTERED == s ||
SELF_ADMINISTERED_BY_RANGE == s))
&& isSpecialDoseType(doseDetail))
There are double parentheses after ! And before &&. They can be reduced to a single one.
if (!(PLANNED == s ||
MISSED == s
|| SKIPPED == s ||
SELF_ADMINISTERED == s ||
SELF_ADMINISTERED_BY_RANGE == s)
&& isSpecialDoseType(doseDetail))
Now you can use the rule of inverting logical expressions:
!(a==b|| c==d) ===> a!=b&&c!=d,
Which basically inverts all the operations due to the NOT (!) Operator. Since you will have only && operators left to combine Boolean sub expressions, then you can drop the parentheses.
if (PLANNED != s
&& MISSED != s
&& SKIPPED != s
&& SELF_ADMINISTERED != s
&& SELF_ADMINISTERED_BY_RANGE != s
&& isSpecialDoseType(doseDetail)
)
Now if you have good domain knowledge you could know if you can combine self
Administered into one variable and shipped/missed into another to have something like: neither ( planned nor stoppedOrMissed nor selfAdministered)&& isSpecial. But without such knowledge I would live the expression at this level.
Related
I'm working on a project and the maintainer suggested me to split a method into two because checks dose not allow to exceed a certain cyclomatic complexity.
#Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (other == null || getClass() != other.getClass()) {
return false;
}
final Suppression suppression = (Suppression) other;
return Objects.equals(lineNo, suppression.lineNo)
&& Objects.equals(columnNo, suppression.columnNo)
&& Objects.equals(suppressionType, suppression.suppressionType)
&& Objects.equals(text, suppression.text)
&& Objects.equals(eventSourceRegexp, suppression.eventSourceRegexp)
&& Objects.equals(eventMessageRegexp, suppression.eventMessageRegexp)
&& Objects.equals(eventIdRegexp, suppression.eventIdRegexp)
&& Objects.equals(firstLine, suppression.firstLine)
&& Objects.equals(lastLine, suppression.lastLine);
}
this is the overridden equals method and it is exceeding the maximum cyclomatic complexity limit because of the return statements ig.
He suggested splitting it into two, how can I do that.
I'm a beginner so I don't know about java that much, so if this question is completely invalid, then please tell me😅
I am using Talend to filter out some rows from an excel file and they don't allow block statements. Everything has to be simple logic or using the ternary operator. So the problem is that the code/logic I need will be used across every cell in the column, BUT some of the cells are null, some are Strings and the rest are Strings that represent integers.
My logic needs to be this:
Return true if and only if PlanName == null || PlanName == 0 but as you can tell, it will fail when it tries to run this on a cell that contains the null or the cell that contains a String that isn't a number.
Is it possible to have this logic in java without the try-catch or block statements? This is what I have right now:
input_row.PlanName == null || Integer.parseInt(input_row.PlanName) == 0
Thanks!
Edit: Basically, I just need to write logic that does this:
Return true if input_row.PlanName == null OR if input_row.PlanName == 0
This needs to be done without using block-statements or try-catches because I am using Talend. So I can only use logical operators like && and || and I can use ternary operators as well.
In your situation, i'll go for routines : reusable bunch of code, handy for this kind of rules that would be hard to implement without if/else etc.
You can create two Routines in Talend, with static methods that you would be able to use in a tMap or a tJavaRow.
First Routine to know if your plan is a numeric or not :
public static boolean isNumeric(String strNum) {
if (strNum == null) {
return false;
}
try {
double d = Double.parseDouble(strNum);
} catch (NumberFormatException nfe) {
return false;
}
return true;
}
Then another routine like :
public static boolean correctPlanName(String planName) {
if(Relational.ISNULL(planName)){
return false;
}
else{
if(!isNumeric(planName)){
return false;
}
else {
return true;
}
}
}
Then you call Routines.correctPlanName(input_row.planName) in tMap/tJavaRow.
It should do the trick.
You can use a regular expression to check if the String only contains digits, then check if num == 0.
input_row.PlanName == null || (input_row.PlanName != null && input_row.PlanName.matches("\\d+") && Integer.parseInt(input_row.PlanName) == 0)
Edit: Probably overkill but to cover other cases e.g. floating point types, numbers prefixed with +/-, you could also do:
input_row.PlanName != null && input_row.PlanName.matches("[-+]?\\d*\\.?\\d+") && Double.parseDouble(input_row.PlanName) == 0)
I am trying to split single line if statement into multiline if statement with the same meaning. I have:
if(a || (b && c))
{
/* do smt */
}
but would like to change it to something like if I would have
if(a && b && c)
{
/*do smt*/
}
with the same meaning of
if(a)
{
if(b)
{
if(c)
{
/* do smt */
}
}
}
Thanks!
Boolean algebra can turn this condiiton
a || (b && c) into
(a || b) && (a || c)
so you can do somthing like:
if(a || b)
{
if(a || c){
/* do smt */
}
}
You can't really do this without repeating the body of the if block. You can transform a || b to !(!a && !b), but while this uses an &&, you can't split this up into nested if statements due to the surrounding !(...).
Why do you want to do this in the first place? My assumption would be that the three conditions a, b and c are very long and/or complex. If this is the case, I'd suggest one of the following:
declare three boolean variables with descriptive names and use those in the condition
boolean isLoggedIn = // some really long data base lookup
boolean isGuest = // more data base stuff
boolean guestCanEdit = // a complex boolean expression
if (isLoggedIn || (isGuest && guestCanEdit)) { ...
define three methods performing the above checks and use those in the if
if (isLoggedIn(user) || (isGuest(user) && guestCanEdit(topic))) { ...
Note, however, that the first version does not use short-circuiting, i.e. all the conditions will be evaluated, even if the first is already true or the second is false. This should be avoided if any of the conditions in computationally expensive or e.g. if the third check is only possible if the second succeeds (e.g. after a null check).
Concerning your comment: The condition
if (list.isEmpty() ||
(!list.isEmpty() && list.getLast().compareTo(heap.peek().value) <= 0))
is not really that long, and I would not suggest any of the above methods for this, as it will not get much shorter that way. But you can shorten it, because the b part is redundant. Due to the short-circuiting of ||, (b && c) are only evaluated if !a, and since your b is !a, you can shorten it to just a || c
if (list.isEmpty() || list.getLast().compareTo(heap.peek().value) <= 0)
If your goal is to count how many times compareTo is called, you can use this:
if (! list.isEmpty() && list.getLast().compareTo(heap.peek().value) <= 0)
Now this is just b && c, with the a part entirely missing. Note that this is not equivalent to a || (b && c) anymore, but in this case that's a good thing, because due again to the short-circuiting, compareTo would actually not be called in a || c if a already evaluated to true.
The need for this is not very clear, but you could do this: Make it in a function:
function codeToDo() {
// your code to execute on condition
}
if (a) {
codeToDo();
else if (b) {
if (c) {
codeToDo();
}
}
if(a || b)
{
if(a || c){
/* do smt */
}
}
To further handle if(a||b) part, apply:
if(a){
/*do task1*/
}else if(b){
/*do task1*/
}
Note that in the if(a) as well as else if(b), you are running same code;i.e. task1.
Yes you can do this, but perhaps you shouldn't.
if (a && b) statement;
is exactly equivalent to
if (a){
if (b){
statement;
}
}
But the same can't be said for if (a || b): you'd need to write statement; in more than one place:
if (a){
statement;
} else if (b){
statement;
}
That said, || does distribute across &&, even with the short-circuiting property:
So
if (a || b && c/*redundant parentheses removed*/){
statement;
}
can be written as
if ((a || b) && (a || c)){
statement;
}
which, from above, is
if (a || b){
if (a || c){
statement;
}
}
which, although unnecessarily obfuscated, is what you want.
I'm trying to do something to the effect of:
if (firstChoice == A || B && secondChoice == A || B){
//passes check.
}
Logically, I want this to pass if the first and second choice are either A or B. Is this syntax valid? Is there a better way to do it?
You can't do == A || B; you can do this (but shouldn't, see below):
if ((firstChoice == A || firstChoice == B) &&
(secondChoice == A || secondChoice == B)) {
That's about as readable as you're going to get it. Breaking it over a line makes it easier to follow the logic; horizontal scrolling is almost always a bad thing, and breaking it at the && operator is the most readable way.
However, there's a way to make it more readable: create a helper method, which does what you want.
private boolean isAorB(YourObject choice) {
return choice == A || choice == B;
}
Then your if statement would be:
if(isAorB(firstChoice) && isAorB(secondChoice)) {
This would be much more readable for future readers, including yourself, which is what you're really going for here.
if (((firstChoice == A) || (firstChoice == B)) && ((secondChoice == A) || secondChoice == B)))
{
//passes check.
}
if ((firstChoice == A || firstChoice == B) && (secondChoice == A || secondChoice == B)) {
//do stuff
}
The thing to note here is that stuff like (firstChoice == A || B) makes sense when you read "firstChoice is equal to A or B" in your head but it doesn't make sense to Java. The left and right side of the || operator have to evaluate to a boolean. 'B' is not a boolean type (I'm assuming), but the condition firstChoice == B is.
Also, you can use parentheses to mark the order of operations, like you do with normal arithmetic. Even if they are not needed, it usually helps with readability.
As I mentioned in a comment and others have mentioned, there's no shorthand for saying "if X equals A or B or C or..." or anything like that. You have to say if (x == a || x == b || x == c), etc. (COBOL does allow that kind of expression, but unfortunately this useful feature hasn't found its way into the design of too many other languages.)
You can say:
if (isOneOf(firstChoice, A, B) || isOneOf(secondChoice, A, B)) {
...
}
if you define an isOneOf method like this:
#SuppressWarnings("unchecked")
public static <T> boolean isOneOf(T obj, T... choices) {
for (T choice : choices) {
if (choice.equals(obj)) {
return true;
}
}
return false;
}
[Note that this allows for more than two choices.]
I use PMD to check my code. It gives me very useful hints in most cases, but I can't figure out what could be improved in the following scenario.
The original code looks something like this:
if ((getSomething() != null && getSomethingElse() != null)
|| (getSomething() == null && getSomethingElse() == null))
{
...
}
PMD tells me:
Sometimes two 'if' statements can be consolidated by separating their
conditions with a boolean short-circuit operator.
For simplicity, let's just use a and b as boolean variables. Then this piece of code looks like this:
if ((!a && !b) || (a && b))
This can be transformed to one of the following:
if ((!a || b) && (a || !b))
if (!(a^b))
and finally
if (a==b)
So I simplified my code to
if ((getSomething() == null) == (getSomethingElse() == null))
However, PMD keeps complaining (in fact about all three versions). Is this a false positive or is there a better way of writing the if-condition?
The problem was something different. The if-statement was the only code inside another if (the code comes from a validation-method):
if (...)
{
...
}
else if (...)
{
...
}
else if (...)
{
if ((getSomething() == null) == (getSomethingElse() == null))
{
...
}
}
What the PMD-message means, is that I could combine the conditions of the last else-if and the inner if-clause:
if (...)
{
...
}
else if (...)
{
...
}
else if (... && ((getSomething() == null) == (getSomethingElse() == null)))
{
...
}
However, I'm not sure, if I'll do this, because the original version seems much clearer to understand.
if ((a != null) && (b != null) && (a==b))
..although personally, I'd do the null checking prior to this if statement so I could handle the a == null and b == null cases individually
The issue is that large blocks of conditionals are difficult to reason about.
OTOH, not every warning PMD emits needs to be paid attention to--consider the ROI. Is it worth refactoring or restructuring to make it cleaner? Can the same functionality be handled in a different way?
If it's not worth it, don't bother.