IF condition with OR value - java

I would like to know if is possibile re-write an if like this
int var = 0;
if ( var == 1 || var == 2 )
{
//...
}
in somethings like this
int var = 0;
if ( var == (1 || 2) )
{
//...
}
or similar. Thanks

|| stands for or operator so it needs a condition on both of its sides so this is incorrect
as you are putting integer on both the sides of the || operator

According to the Java Language Specification
Each operand of the conditional-or operator must be of type boolean or Boolean, or a compile-time error occurs.
so no, there is no better (and faster) way to code your condition.
(The same rules apply to the conditional-and operator)

There is no such syntax with if in java.
If you have a large set of values in the if condition, you may use switch instead:
int var = ...;
switch(var) {
case 1:
case 2:
// ...
break;
default:
//else case
break;
}
Edit:
With Java 8, you can also write:
int var = ...;
if (IntStream.of(1, 2, 3, 4).anyMatch(i -> var == i)) {
//...
}

No, that is not possible in Java. What you're asking is something similar to sql IN operator.
if(var == (1 || 2)) could easily be translated to if(var IN [1,2]), but Java doesn't suport that either.
As close you can get to is to use a collection :
if(Arrays.asList(1,2).contains(var)){
or a String
if("1_OR_2".contains(String.valueOf(var))
One other approach could be to build a function like
public static final boolean in(final int var, final int... vals) {
for (int val : vals) {
if (var == val) {
return true;
}
}
return false;
}
And then, you'll call : if(in(var,1,2)){ .
Or you could build a wrapper for Integer, and add in method there, so the method call may sound more natural( if value x in [val1,val2 ... valN])
public final class Int {
private final Integer val;
public Int(final int val) {// avoid passing nulls
this.val = val;
}
public boolean in(final int... vals) {
for (int val : vals) {
if (this.val.equals(val)) {
return true;
}
}
return false;
}
public static void main(final String[] args) {
System.out.println(new Int(1).in(1, 2, 3));
}
}

Related

Compare value of enum

Implementing a infix to postfix calculator and need to check if an operator has a lower precedence than another. Here's what I have so far:
public enum Operators {
ADD('+', 2), SUBTRACT('-', 2), MULTIPLY('*', 4), DIVIDE('/', 4);
private char operator;
private int precedence;
Operators(char operator, int precedence) {
this.operator = operator;
this.precedence = precedence;
}
public char getOperator() {
return operator;
}
public int getPrecedence() {
return precedence;
}
}
private static boolean isOperator(char c) {
return c == Operators.ADD.getOperator() || c == Operators.SUBTRACT.getOperator()
|| c == Operators.MULTIPLY.getOperator() || c == Operators.DIVIDE.getOperator();
}
private static boolean isLowerPrecedence(char ch1, char ch2) {
// STUCK HERE
}
I've tried a number of different things to check the precedence of the char that is passed in but to no avail. Is there an easy way to compare two values of an enum? Will I have to create a loop?
It's easy to compare if you have a method that translates a "operator" char to an enum value.
For example:
static Operators getOperatorForChar(char op) {
for(Operators val: values())
if(op == val.operator)
return val; //return enum type
return null;
}
And then you can implement your method using:
private static boolean isLowerPrecedence(char ch1, char ch2) {
//assuming intention is to compare precedence of ch1 to that of ch2
return getOperatorForChar(ch1).precedence < getOperatorForChar(ch2).precedence;
}
You can loop the values of enum to match the right operator and compare its precedences:
private static boolean isLowerPrecedence(char ch1, char ch2) {
Integer first = null;
Integer second = null;
for (Operators o: Operators.values()) {
if (o.getOperator() == ch1) {
first = o.getPrecedence();
}
if (o.getOperator() == ch2) {
second = o.getPrecedence();
}
}
return (first != null && second !=null && first < second);
}
Returning boolean when the operator has not been found might be confusing. I recommend you to throw an exception in such case instead.
...
if (first == null || second ==null) throw new Exception("Operator not found.");
return first < second;
Or, you can compare the precedence like this:
private static boolean isLowerPrecedence(Operators operatorFirst, Operators operatorSecond) {
if(operatorFirst.getPrecedence() < operatorSecond.getPrecedence()){
return true;
} else {
return false;
}
}
Of course, it can be written as:
return operatorFirst.getPrecedence() < operatorSecond.getPrecedence();
By taking a look at this question, you can find out Java handles types comparisons via the Comparable and Comparator interfaces.
Of course, they are meant for more complex situations that this one, but I think you should take them into account so that you can see the proper way to deal with the set of ordering algorithms provided by the standard Java library.
Since you can't override default Enum's compareTo (it is declared as final), you can implement your own Comparator as such:
public class OperatorsComparator implements Comparator<Operators> {
#Override
public int compare(Operators o1, Operators o2) {
return o1.getPrecedence() - o2.getPrecedence();
}
}
Then you're going to need some kind of way to find the right Operators value from the char you give in:
private static Operators findOperator(char c){
for(Operators op : Operators.values()){
if(op.getOperator() == c)
return op;
}
return null;
}
By using a substraction between the two precedences and the previous Operators finder, you can implement your isLowerPrecedence method like this:
public static boolean isLowerPrecedence(char c1, char c2) throws Exception {
Operators o1 = findOperator(c1);
Operators o2 = findOperator(c2);
if(o1 == null || o2 == null)
throw new Exception("Invalid operators");
return new OperatorsComparator().compare(o1, o2) <= 0;
}
By comparing precedences this way, you'll get that o1 will be marked as lower precedence even if it has the same precedence as o2, as default behaviour.
Beware of the characters you try to use as operator, since you'll need to catch the Exception if anything goes wrong
Execution example:
System.out.println(isLowerPrecedence('+', '-'));
System.out.println(isLowerPrecedence('+', '*'));
System.out.println(isLowerPrecedence('/', '-'));
System.out.println(isLowerPrecedence('/', '*'));
System.out.println(isLowerPrecedence('*', '-'));
prints these messages:
true
true
false
true
false
You can use EnumLookup helper class proposed in this answer of mine (source code of EnumLookup there).
Upon redesining your Operators enum a little (I strongly suggest using a singular class name), you get:
public enum Operator {
ADD('+', 2), SUBTRACT('-', 2), MULTIPLY('*', 4), DIVIDE('/', 4);
private static final EnumLookup<Operator, Character> BY_OPERATOR_CHAR
= EnumLookup.of(Operator.class, Operator::getOperatorChar, "operator char");
private final char operatorChar;
private final int precedence;
Operator(char operatorChar, int precedence) {
this.operatorChar = operatorChar;
this.precedence = precedence;
}
public char getOperatorChar() {
return operatorChar;
}
public int getPrecedence() {
return precedence;
}
public static EnumLookup<Operator, Character> byOperatorChar() {
return BY_OPERATOR_CHAR;
}
}
private static boolean isOperator(char c) {
return Operator.byOperatorChar().contains(c);
}
private static boolean isLowerPrecedence(char ch1, char ch2) {
return Operator.byOperatorChar().get(ch1).getPrecedence() < Operator.byOperatorChar().get(ch2).getPrecedence();
}
The main drawback of this approach is that your char gets boxed into Character, but unless performance is critical for your application, I wouldn't worry about that (readability should be more important).

Incompatible types: int and boolean. How to re-write if statement? [duplicate]

This question already has answers here:
I keep getting a "The operator == is undefined for the argument type(s) boolean, int" and have no idea how to fix it
(2 answers)
Closed 6 years ago.
I'm trying to write this if statement:
public void currentState(boolean x)
{
boolean timeOn = true;
boolean timeOff = false;
if (x ==(0)) {
x = timeOff;
} else {
x = timeOn;
}
}
if (x ==(0) does not work which I fully understand, but how would you re-write this so that x can be compared to 0?
You can only use two values - true and false if you're dealing with boolean. 0 is not one of them.
You could write the statement like this:
if (x == false) {
x = timeOff;
} else {
x = timeOn;
}
However, this if statement is meaningless. It is equivalent to:
if (x == false) {
x = false;
} else {
x = true;
}
It basically says "if x is false, make it false". You might want to reconsider what your method does.
EDIT:
You can also rewrite it like this:
if (x == true) {
x = timeOff;
} else {
x = timeOn;
}
which is equivalent to:
if (x) {
x = timeOff;
} else {
x = timeOn;
}
which is equivalent to:
x = !x;
if (x) { // This will do.
x = timeOff;
} else {
x = timeOn;
}
if statements can have only a boolean result arguments. so x is already a boolean with a value like true/false. you can't compare boolean values to 0.
== is a relational operator that compare 2 values if they are equal, that results into a boolean output. There are many relational operator that compares 2 value according to that operator. You can read it here to fully understand how it works. Summary of Operators.
In Java,a boolean data type can have only two possible values true and false.So,It can not be compared to 0.So either you need to make x as an int or you should check x with a valid boolean value like if(x == true)/if(x == false)
Try replacing x==(0) in your code with !x as follows, x is a boolean. if x is (false or 0 or null), !x will be true, and anyother case !x will return false as required for you..
public void currentState(boolean x)
{
boolean timeOn = true;
boolean timeOff = false;
if (!x) {
x = timeOff;
} else {
x = timeOn;
}
}
Java is a type safe language. Therefore you can't use the ==operator to compare two incompatible types, in this case boolean and the int literal value 0. So you can either do one of these two things:
Pass an int parameter
public void currentState(int x){
if (x == 0) {
//code
} else {
//code
}
}
Pass a boolean as in your orginal case
public void currentState(boolean x){
if (x) {
//code
} else {
//code
}
}

I need to correct the code to return true if value is in array, otherwise return false. but this code return both of them using (for in) loop

int[] Scores={2,3,8,7,1,4,9};
int kema=7;
boolean T=true;
boolean F=false;
for(int value : Scores)
if(kema == value) {
System.out.println(T);
break;
}
system.out.println(F);
I need to correct the code to return true if value is in array, otherwise return false. but this code return both of them using (for in) loop.
Like the user Jack suggested in the comments to your question. Use a boolean to keep track of if the value was found in the array.
int[] Scores={2,3,8,7,1,4,9};
int kema = 7;
boolean T = true;
boolean F = false;
boolean found = false;
for(int value : Scores) {
if(kema == value) {
found = true;
break;
}
}
if(found) {
System.out.println(T);
} else {
System.out.println(F);
}
You also don't need to have two booleans representing true and false, one boolean is either true or false. So the following could also work:
int[] Scores={2,3,8,7,1,4,9};
int kema = 7;
boolean found = false;
for(int value : Scores) {
if(kema == value) {
found = true;
break;
}
}
System.out.println(found);
In Java 8+ you can use an IntStream1 and something like
System.out.println(IntStream.of(Scores).anyMatch(x -> x == kema));
In earlier versions of Java, you might extract the logic to a method like
public static boolean contains(int[] arr, int val) {
for (int v : arr) {
if (v == val) {
return true;
}
}
return false;
}
And then call it like
System.out.println(contains(Scores, kema));
1Also, by convention, variables should start with lower case letter.

Return multiple values from void and boolean methods

I have the following problem: Having a boolean static method that computes similarity between two integers, I am asked to return 4 results:
without changing the return type of the method, it
should stay boolean.
without updating/using the values of external variables and objects
This is what I've done so far (I can't change return value from boolean to something else, such as an int, I must only use boolean):
public static boolean isSimilar(int a, int b) {
int abs=Math.abs(a-b);
if (abs==0) {
return true;
} else if (abs>10) {
return false;
} else if (abs<=5){
//MUST return something else, ie. semi-true
} else {
//MUST return something else, ie. semi-false
}
}
The following is bad practice anyway, but If you can try-catch exceptions you can actually define some extra outputs by convention. For instance:
public static boolean isSimilar(int a, int b) {
int abs = Math.abs(a-b);
if (abs == 0) {
return true;
} else if (abs > 10) {
return false;
} else if (abs <= 5){
int c = a/0; //ArithmeticException: / by zero (your semi-true)
return true;
} else {
Integer d = null;
d.intValue(); //NullPointer Exception (your semi-false)
return false;
}
}
A boolean can have two values (true or false). Period. So if you can't change the return type or any variables outside (which would be bad practice anyway), it's not possible to do what you want.
Does adding a parameter to the function violate rule 2? If not, this might be a possible solution:
public static boolean isSimilar(int a, int b, int condition) {
int abs = Math.abs(a - b);
switch (condition) {
case 1:
if (abs == 0) {
return true; // true
}
case 2:
if (abs > 10) {
return true; // false
}
case 3:
if (abs <= 5 && abs != 0) {
return true; // semi-true
}
case 4:
if (abs > 5 && abs <= 10) {
return true; // semi-false
}
default:
return false;
}
}
By calling the function 4 times (using condition = 1, 2, 3 and 4), we can check for the 4 results (only one would return true, other 3 would return false).

What is the best way to test this? Binary digits with 4 positions

Consider 4 input fields A, B, C and D on a web surface. The user can fill any of these arbitrary. There are 16 combinations of how to fill these fields. The ones allowed are:
A B C D
-------
1 0 0 0
1 1 0 0
1 1 1 0
1 1 1 1
where 1 means not null and 0 means null.
I am using the MVC pattern with jsf. I don't want the logic to be in the view, but rather in the controller. What is the best way to check this in Java?
I implemented two solutions so far:
Solution 1:
#Override
public boolean isInputInvalid(Integer a, Integer b, Integer c, Integer d) {
if (isNotSet(a) && isNotSet(b) && isNotSet(c) && isNotSet(d) {
return true;
}
return (firstParameterDoesNotExistAndSecondDoesExist(a, b)) || (firstParameterDoesNotExistAndSecondDoesExist(b, c)) || (firstParameterDoesNotExistAndSecondDoesExist(c, d));
}
private boolean firstParameterDoesNotExistAndSecondDoesExist(Integer firstParameter, Integer secondParameter) {
return isNotSet(firstParameter) && !isNotSet(secondParameter);
}
private boolean isNotSet(Integer parameter) {
return parameter == null;
}
Solution 2:
public boolean isInputValid(Integer a, Integer b, Integer c, Integer d) {
if (exists(a) && !exists(b) && !exists(c) && !exists(d) || //
exists(a) && exists(b) && !exists(c) && !exists(d) || //
exists(a) && exists(b) && exists(c) && !exists(d) || //
exists(a) && exists(b) && exists(c) && exists(d)) {
return true;
}
return false;
}
private boolean exists(Integer level) {
return level != null;
}
Note:
The first methods checks if input is invalid, while the second checks if input is valid (note the names of the methods).
I wrote 16 unit test cases, which all run green with both versions.
Do you have any hints/tips/tricks on how to get the code even more readable?
Valid combinations are: 1000, 1100, 1110 and 1111
If you only care about readability:
public static List<String> validOptions = Arrays.asList("1000","1100","1110","1111");
public boolean isValid(Integer a, Integer b, Integer c, Integer d)
{
StringBuilder sb = new StringBuilder();
sb.append(a==null ? 0 : 1);
sb.append(b==null ? 0 : 1),
sb.append(c==null ? 0 : 1);
sb.append(d==null ? 0 : 1);
return validOptions.contains(sb.toString());
}
Note that this is not the fastest or cleanest solution (wastes some CPU and memory)
To solve this for an arbitrary number of parameters, pass in true or false (if not null / null) in this:
static boolean isValid(boolean... params) {
boolean set = true;
for (boolean param : params) {
if (!set && param) return false;
set = param;
}
return params[0];
}
Or much cooler (and IMHO readable), but less performant, use regex on the array's toString():
static boolean isValid(boolean... params) {
return Arrays.toString(params).matches("\\[true(, true)*(, false)*]");
}
which ever implementation you use, you would call it like:
if (isValid(a != null, b != null, c != null, d != null))
Not fancy but fast and simple:
static boolean isValid(boolean a, boolean b, boolean c, boolean d) {
return a && (b || !c) && (c || !d);
}
Call:
isValid(a != null, b != null, c != null, d != null);
I don't really understand why you need this. Rather than a method that tests if input is valid, it would be much better to only allow valid input in the first place.
// This method is private, so you can't call it with arbitrary arguments.
private void privateMethod(Integer a, Integer b, Integer c, Integer d) {
// do something();
}
public void method(int a) {
privateMethod(a, null, null, null);
}
public void method(int a, int b) {
privateMethod(a, b, null, null);
}
public void method(int a, int b, int c) {
privateMethod(a, b, c, null);
}
public void method(int a, int b, int c, int d) {
privateMethod(a, b, c, d);
}
The way to modify this to any number of arguments (not just 4) is to have a method with signature
public void method(int... a)
Then, if the length of the array passed is less than the required length, you can just use null for the remaining inputs.
If this does not address your problem, I think you should consider editing your question to give an example of your use case, because I suspect there is a better way to achieve what you require.
You could create a pattern with a two dimensional array.
The advantage is that it is easy to adjust, and add additional information to it.
Here is a tiny example with your conditions.
In the end all you have to read is the pattern that is initialized in the static block, which is quite easy to read.
// Every boolean array in a dimension represents a valid pattern
private static boolean[][] pattern;
static {
pattern = new boolean[4][4];
pattern[0] = new boolean[]{true, false, false, false};
pattern[1] = new boolean[]{true, true, false, false};
pattern[2] = new boolean[]{true, true, true, false};
pattern[3] = new boolean[]{true, true, true, true};
}
public static void main(String[] args) {
// Testing an invalid combination
System.out.println(test(new Integer[]{1,null,3,null}));
// Testing a valid combination
System.out.println(test(new Integer[]{1,2,3,null}));
}
private static boolean test(Integer[] input) {
// cast the input to a boolean array that can be compared to the pattern.
boolean[] arr = createArr(input);
for(int i = 0;i<pattern.length;++i) {
if(Arrays.equals(pattern[i], arr)) { // Check if the pattern exists in the list of valid pattern. If it exists, then this is a valid combination
return true;
}
}
// the loop never found a valid combination, hence it returns false.
return false;
}
// This is just a helping method to create a boolean array out of an int array. It casts null to true and !null to false.
private static boolean[] createArr(Integer[] input) {
boolean[] output = new boolean[input.length];
for(int i = 0;i<input.length; ++i) {
output[i] = input[i] != null;
}
return output;
}
Yet another solution. Involves more code but for me it's easier to understand:
boolean isInputInvalid(Object ... args) {
int notNullDataIndex = -1;
for (int i = args.length - 1; i >= 0; i--) {
if (args[i] != null) {
notNullDataIndex = i;
break;
}
}
if (notNullDataIndex < 0) return false;
for (int i = notNullDataIndex; i >= 0; i--) {
if (args[i] == null) return false;
}
return true;
}

Categories

Resources