I was wondering whether its possible in java to evaluate multiple variables together in if-else condition like in python.
actual code
if(abc!=null && xyz!=null)
{//...}
dummy code
if(abc && xyz !=null)
{// will it be possible}
FIRST DRAFT
You can write smth like this:
boolean notNull(Object item) {
return item != null;
}
then you could use it like:
if (notNull(abc) && notNull(xyz)) {
//...
}
UPDATE 1:
I came up with a new idea, write function using varargs like:
boolean notNull(Object... args) {
for (Object arg : args) {
if (arg == null) {
return false;
}
}
return true;
}
usage: (you can pass to function multiple arguments)
if (notNull(abc, xyz)) {
//...
}
UPDATE 2:
The best approach is to use library apache commons ObjectUtils,
it contains several ready to use methods like:
allNotNull(Object... values),
anyNotNull(Object... values)
or firstNonNull(T... values)
the only way this would work is if abc was a boolean (and it wouldn't do what you're hoping it would do, it would simply test if abc == true). There is no way to compare one thing to multiple things in Java.
It's Impossible in java, you can use Varargs:
public boolean checkAnything(Object args...){
for(Object obj args){
if(...)
}
return ....;
}
See also:
Varargs
String… parameter in Java
Its not possible to that in Java. Instead you can do something like this:-
public boolean checkForNulls(Object... args){
List<Object> test = new ArrayList<Object>(Arrays.asList(args));
return test.contains(null); // Check if even 1 of the objects was null.
}
If any of the items is null, then the method will return true, else it'll return false. You can use it as per your requirements.
IMHO First is the better way and possible way.
Coming to second way ..if they are boolean values
if(abc && xyz )
{//...}
Related
I am using AssertJ extracting() method with Java8 lambdas and mapping some fields to BigDecimal, then asserting the resulting array. But I need to compare BigDecimal using compareTo() and not with equals() (because of this). How can I do that?
Example:
Actual actual = performTest();
Assertions.assertThat(actual)
.extracting(
Actual::getName, // returns String
Actual::getValue // returns BigDecimal
)
.containsExactly(
"abc", // ok, String equals comparison
new BigDecimal("1.1") // NOT OK, equals comparison, but I need compareTo comparison
);
Edit: I am looking for a fluent way to do this, because of course I can split this into multiple different Asserts and compare it that way, or put everything in one giant Condition.
You can use BigDecimalComparator like :
Actual actual = performTest();
Assertions.assertThat(actual)
.extracting(
Actual::getName, // returns String
Actual::getValue // returns BigDecimal
)
.usingComparatorForType(BigDecimalComparator.BIG_DECIMAL_COMPARATOR, BigDecimal.class)
.containsExactly("abc", new BigDecimal("1.1"));
If #assylias's solution doesn't work, you can always use a custom Condition.
assertThat(new BigDecimal("1.1")).has(new Condition<BigDecimal>() {
#Override
public boolean matches(BigDecimal s) {
return s.compareTo(new BigDecimal("1.1")) == 0;
}
});
Wrap it in a functional interface for a nicer syntax.
Edit: Using the tuple extractor in your example:
assertThat(foo).extracting("name", "value").has(new Condition<Object[]>() {
#Override
public boolean matches(Object[] value) {
return new BigDecimal("1.1").compareTo(value[1]);
}
});
Without tuple extractor:
Assertions.assertThat(actual).has(actualValue("abc", new BigDecimal("1.1")));
// Hide this somewhere and import static :)
public static Condition<Actual> actualValue(String expectedName, BigDecimal expectedValue) {
return new Condition<Actual>() {
#Override
public boolean matches(Actual value) {
return expectedName.equals(value.getName()) && value.getValue().compareTo(expectedValue) == 0;
}
};
}
I would use matches if it's a one time assertion:
assertThat(actual).matches(a -> a.getName().equals("abc") && p.getValue().compareTo(new BigDecimal("1.1")) == 0);
If you plan to reuse the assertion, I would create a condition as suggested by #fabienbk.
Often, I can see a code constructs like following:
if(a == null || b == null || c == null){
//...
}
I wonder if there is any widely used library (Google, Apache, etc.) to check against nullity for multiple objects at once, e.g.:
if(anyIsNull(a, b, c)){
//...
}
or
if(allAreNulls(a, b, c)){
//...
}
UPDATE:
I perfectly know how to write it by myself
I know it can be the result of the poor program structure but it's not a case here
Let's make it more challenging and replace original example with something like this:
if(a != null && a.getFoo() != null && a.getFoo().getBar() != null){
//...
}
UPDATE 2:
I've created a pull request for Apache Commons Lang library to fix this gap:
Issue: https://issues.apache.org/jira/browse/LANG-781
PR: https://github.com/apache/commons-lang/pull/108
These will be incorporated in commons-lang, version 3.5:
anyNotNull (Object... values)
allNotNull (Object... values)
In Java 8, you could use Stream.allMatch to check whether all of the values match a certain condition, such as being null. Not much shorter, but maybe a bit easier to read.
if (Stream.of(a, b, c).allMatch(x -> x == null)) {
...
}
And analogeously for anyMatch and noneMatch.
About your "more challenging example": In this case, I think there is no way around writing a lazy-evaluated conjunction of null-checks, like the one you have:
if (a != null && a.getFoo() != null && a.getFoo().getBar() != null) {
...
}
Any of the other approaches, using streams, lists, or var-arg methods, would try to evaluate a.getFoo() before a has been tested not to be null. You could use Optional with map and method pointers, that will be lazily evaluated one after the other, but whether this makes it any more readable is debatable and may vary from case to case (particularly for longer class names):
if (Optional.ofNullable(a).map(A::getFoo).map(B::getBar).isPresent()) {
...
}
Bar bar = Optional.ofNullable(a).map(A::getFoo).map(B::getBar).orElse(null);
Another alternative might be to try to access the innermost item, but I have a feeling that this is not considered good practice, either:
try {
Bar bar = a.getFoo().getBar();
...
catch (NullPointerException e) {
...
}
Particularly, this will also catch any other NPEs after accessing that element -- either that, or you have to put only the Bar bar = ... in the try and everything else in another if block after the try, nullifying any (questionable) gains in readability or brevity.
Some languages have a Safe Navigation Operator, but it seems like Java is not one of them. This way, you could use a notation like a?.getFoo()?.getBar() != null, where a?.getFoo() will just evaluate to null if a is null. You could emulate behavior like this with a custom function and a lambda, though, returning an Optional or just a value or null if you prefer:
public static <T> Optional<T> tryGet(Supplier<T> f) {
try {
return Optional.of(f.get());
} catch (NullPointerException e) {
return Optional.empty();
}
}
Optional<Bar> bar = tryGet(() -> a.getFoo().getBar(););
EDIT 2018: As of Apache Commons lang 3.5, there has been ObjectUtils.allNotNull() and ObjectUtils.anyNotNull().
No.
None of Apache Commons Lang (3.4), Google Guava (18) and Spring (4.1.7) provide such a utility method.
You'll need to write it on your own if you really, really need it. In modern Java code, I'd probably consider need for such a construct a code smell, though.
You could also use something like the following method. It allows you to pass as many parameters as you want:
public static boolean isAnyObjectNull(Object... objects) {
for (Object o: objects) {
if (o == null) {
return true;
}
}
return false;
}
You call it with as many parameters as you like:
isAnyObjectNull(a, b, c, d, e, f);
You could do something similar for areAllNull.
public static boolean areAllObjectsNull(Object... objects) {
for (Object o: objects) {
if (o != null) {
return false;
}
}
return true;
}
Note: you could also use the ternary operator instead of if (o == null). The two methods shown here have no error handling. Adjust it to your needs.
Objects.requireNonNull
It is possible with help of Objects class and its requireNonNull method.
public static void requireNonNull(Object... objects) {
for (Object object : objects) {
Objects.requireNonNull(object);
}
}
Apache commons-lang3 since version 3.11 has method ObjectUtils.allNull(Object... values)
ObjectUtils.allNull(obj1, obj2, obj3);
I was looking for a solution, but I don't have apache as a dependency yet and it felt silly to me to add it just for the allNonNull method. Here is my plain vanilla java solution using Predicate#and() / Predicate#or() like this:
private static boolean allNonNull(A a) {
Predicate<A> isNotNull = Objects::nonNull;
Predicate<A> hasFoo = someA -> someA.foo != null;
Predicate<A> hasBar = someA -> someA.foo.bar != null;
return Optional.ofNullable(a)
.filter(isNotNull.and(hasFoo.and(hasBar)))
.isPresent();
}
Note: for the anyNonNull, simply use the or() method instead of and().
When invoked, would give the following output:
System.out.println(isValid(new A(new Foo(new Bar())))); // true
System.out.println(isValid(new A(new Foo(null)))); // false
System.out.println(isValid(new A(null))); // false
System.out.println(isValid(null)); // false
Class definitions used:
public static class A {
public A(Foo foo) {
this.foo = foo;
}
Foo foo;
}
public static class Foo {
public Foo(Bar bar) {
this.bar = bar;
}
Bar bar;
}
public static class Bar { }
Simply as that:
Stream.of(a,b,c).allMatch(Objects::nonNull)
You can create a list of you objects and use yourList.contains(null) in it.
List < Object > obList = new ArrayList < Object > ();
String a = null;
Integer b = 2;
Character c = '9';
obList.add(a);
obList.add(b);
obList.add(c);
System.out.println("List is " + obList);
if (obList.contains(null)) {
System.out.println("contains null");
} else {
System.out.println("does not contains null");
}
DEMO
This question already has answers here:
Best way to format multiple 'or' conditions in an if statement
(8 answers)
Closed 1 year ago.
Basically, what I want to do is check two integers against a given value, therefore, classically what you would do is something like this:
//just to get some values to check
int a, b;
a = (int)(Math.random()*5);
b = (int)(Math.random()*5);
//the actual thing in question
if(a == 0 || b == 0)
{
//Then do something
}
But is there a more concise format to do this? Possibly similar to this (which returns a bad operand type):
//just to get some values to check
int a, b;
a = (int)(Math.random()*5);
b = (int)(Math.random()*5);
//the actual thing in question
if((a||b) == 0)
{
//Then do something
}
You can do the following in plain java
Arrays.asList(a, b, c, d).contains(x);
Unfortunately there is no such construct in Java.
It this kind of comparison is frequent in your code, you can implement a small function that will perform the check for you:
public boolean oneOfEquals(int a, int b, int expected) {
return (a == expected) || (b == expected);
}
Then you could use it like this:
if(oneOfEquals(a, b, 0)) {
// ...
}
If you don't want to restrict yourselft to integers, you can make the above function generic:
public <T> boolean oneOfEquals(T a, T b, T expected) {
return a.equals(expected) || b.equals(expected);
}
Note that in this case Java runtime will perform automatic boxing and unboxing for primitive types (like int), which is a performance loss.
As referenced from this answer:
In Java 8+, you might use a Stream and anyMatch. Something like
if (Stream.of(b, c, d).anyMatch(x -> x.equals(a))) {
// ... do something ...
}
Note that this has the chance of running slower than the other if checks, due to the overhead of wrapping these elements into a stream to begin with.
I think that a bit-wise OR:
if ((a | b) == 0) . . .
would work if you want to check specifically for 0. I'm not sure if this saves any execution time. More to the point, it makes for cryptic code, which will make the future maintainer of this code curse you (even if its yourself). I recommend sticking with the more-typing option.
Bah. I misread OP's original logic.
Another go...
If you want to test whether any one of many variables is equal to an expected value, a generic function might work:
public <T> boolean exists(T target, T... values) {
for (T value : values) {
if (target == null) {
if (value == null) {
return true;
}
} else if (target.equals(value)) {
return true;
}
}
return false;
}
This will work for any number of objects of one type. Primitives will be autoboxed so it will work with them as well. Your original code will be something like:
if (test(0, a, b)) {
// do something
}
(A better method name would be desperately needed to even consider whether this an improvement over what you have now. Even if the test expands to 3 or 4 variables, I question the need for this kind of thing.) Note that this also works with arrays:
int[] values = { . . . };
if (test(0, values)) { . . .
and it can be used to test whether an array (or any of a collection of variables) is null.
if(a == 0 || b == 0)
{
//Then do something
}
Why not keep it readable? What is not concise about this? On the other hand,
a = (int)(Math.random()*5);
involves an unnecessary cast. Why not just use Random and invoke nextInt()?
For this example, you can do
if (a * b == 0)
or for more variables
if (a * b * c * d == 0)
while more concise it may not be as clear. For larger values, you need to cast to a long to avoid an overflow.
You could put the integers in a set and see if it contains the given value. Using Guava:
if(newHashSet(a, b).contains(0)){
// do something
}
But two simple int comparisons are probably easier to understand in this case.
Here's a modification of #buc's answer that can take any number of any arguments:
public <T> boolean oneOfEquals(T expected, T... os) {
for (T o : os) {
if (expected.equals(o)) return true;
}
return false;
}
Even if you have used the bit-wise operation as Ted suggested, the expressions are not equal, since one requires at least one of the variables to be zero and the second requires both of them to be zero.
Regarding your question, there is no such shortcut in Java.
You can try this code:
public static boolean match (Object ref, Object... objects)
{
if (ref == null)
return false;
//
for (Object obj : objects)
if (obj.equals (ref))
return true;
//
return false;
} // match
So if you can check this way:
if (match (reference, "123", "124", "125"))
; // do something
In Java 8 we can achieve the same by using the below method:
private boolean methodName(int variant,int... args){
if(args.length > 0){ return Arrays.stream(args).anyMatch( x -> x == variant); }
return false;
}
The given method will return true if the variant will match any possible input(s). This is used for or condition.
In the same way, if you want to do &&(and) condition then you just need to used other Java 8 methods:
Note: These methods take Predicate as an argument.
anyMatch: return true the moment the first predicate returns true otherwise false.
allMatch: return true if all the predicates return true otherwise false.
noneMatch: return true if none of the predicates return true otherwise false.
Performance Note: This is good when you have enough amount of data to
check as it has some overhead but it works really well when you use
this for enough amount of data. normal way is good for just two
conditions.
There is no special syntax for that. You could make a function for that. Assuming at least Java 1.5:
public <T> boolean eitherOneEquals(T o1, T o2, T expectedValue) {
return o1.equals(expectedValue) || o2.equals(expectedValue);
}
if(eitherOneEquals(o1, o2, expectedValue)) {
// do something...
}
I am really tired of doing all the if null checks, resp. I also want to have a more configurable scenario for this. Let me explain this by an example:
I have a getter() which may return null or '0' in both cases the resp. setter() should not be called passing the getter().
So the implementation is
if(getter() != null && !getter().equals('0')) setter(getter());
this however really anoys me, especially if getter() and setter() are really long method calls and I have to introduce helper variables for this.
I am thinking about a method with parameter
ifNotSet(getter(), setter(), new Object[null, '0']);
which does exactly the same thing. Where the parameters to ifNotSet are
getter - the method to check if it does not equal one of the conditions
setter - the method to call in the way setter(getter) if conditions does not apply
conditions - the conditions which must not apply on evaluation of getter() for the method to be executed
At first sight this does not seem to complicated, it however is! Is anyone aware of a solution to this problem or any kind of implementation?
Thanks!
Update
I've been working some more on the problem, after the feedback of you guys, and found out about the following
private boolean ns(Object[] condition, Object getter) {
boolean ret = false;
for (Object object : condition) {
if(getter) equals or == ??
}
return true;
}
Object[] cond = new Object[] { null, "0" };
Object a;
if (ns(cond, a = getter()))setter(a);
Well, this seemed to be at least a solution if you have a lot of allocations to do. However, if you take a look at the ns() method... the question on the incoming conditions is, whether to use == or equals to do the comparison!?
You can use this way
public boolean checkNotNullOrZero(String s)
{
return (s!=null) && !s.equals("0");
}
Basic use:
if(checkNotNullOrZero(getter()))
{
setter(getter());
}
You can't do what that as in Java methods are not first-class citizens. You could use reflection or anon classes but it would be way more work .
If null and zero are always equivalent for getter then could that be changed to return just one of the two?
If null and zero are always equivalent for setter then could that be changed to normalize the two?
Could you create a method isNullOrZero(x) then you can have
if (!isNullOrZero(getter())) {
setter(getter());
}
Ugly way of doing this literally in Java:
public interface Getter {
public Object get();
}
public interface Caller {
public void call();
}
public void callIfNotNull(Getter getter, Caller caller, Object[] nullObjects) {
Object value = getter.get();
for(Object nullObject : nullObjects) {
if(value==nullObject) {
return;
}
}
caller.call();
}
Usage:
callIfNotNull(new Getter() {
#Override
public Object get() {
return getterMethod();
}
}, new Caller() {
#Override
public void call() {
setter();
}
}, new Object[]{null, '0'});
}
You might need to implement sane way to check for null objects and give reasonable names.
Personnaly, I wouldn't go with this approach. I would try to implement Null Object pattern to resolve an issue.
I want my custom functions to modify / toggle a boolean variable. Let's say that I have code like
if (OK2continue) { findANDclick(new String[]{"id", "menuButton"});}
if (OK2continue) { findANDclick(new String[]{"src", ".*homeicon_calendar.*"}); }
if (OK2continue) { findANDclick(new String[]{"src", ".*cycle_templates.*"});
I want to make sure that the flow of execution stops once any of the findANDclick functions toggles the variable OK2continue
I managed my functions to modify a String variable using StringBuilder.
Can I do the same for boolean type of variable?
I can't say it is equivalent. But using MutableBoolean offers you a mutable boolean wrapper, similar to the concept of StringBuilder a mutable sequence of characters. See this JavaDoc for details.
Push this code into its own method, and use a return:
if (findANDclick(new String[]{"id", "menuButton"})) return;
if (findANDclick(new String[]{"src", ".*homeicon_calendar.*"})) return;
if (findANDclick(new String[]{"src", ".*cycle_templates.*"})) return;
Given that all your method calls are the same, you could also use a loop:
String[][] buttons = {
{"id", "menuButton"},
{"src", ".*homeicon_calendar.*"},
{"src", ".*cycle_templates.*"},
};
for (String[] button: buttons) {
if (findANDclick(button)) return;
}
You might or might not find that more readable.
You need to clarify your reference to your usage of StringBuilder.
Assuming:
You pass reference of the StringBuilder to your method. String is changed in method. If this the case, then see #Gordon Murray Dent's answer.
Your boolean flag is visible in the method but is not passed. A simple Boolean will do.
package sof_6232851;
public class SideEffectingMethod {
static Boolean flag = false;
public static void main(String[] args) {
flag = true;
System.out.format ("flag is %b\n", flag);
clickMe();
System.out.format ("flag is %b\n", flag);
}
/** this method side-effects instance variable flag */
public static void clickMe () {
flag = !flag;
}
}
[edit list item #2 to reply to OP comment]:
Note that #2 is not really recommended. You mention your desire for "readable" code. Side-effecting methods works against that goal.
public class ReturnValuesForFunAndProfit {
public static void main(String[] args) {
presentUI();
}
public static void presentUI() {
if(!clickMe("woof")) return;
if(!clickMe("meow")) return;
if(!clickMe("hello")) return;
}
public static boolean clickMe (String blah) {
// your logic here; this ex. always returns true
return true;
}
}
Well, the concept of StringBuilder is to create a mutable and extendable String wrapper (meaning the string can be extended via append and the like :) ). You'd still have to pass it as a parameter to the method in order to modify it (or use a static var - not recommended).
Since boolean can't be extended, the only similarity would be the parameter to be mutable. So you can use MutableBoolean as Gordon suggested, but you'd still have to pass it.
Another option would be to return a boolean from findANDclick(...) and use the boolean opperators like: findAndClick(...) || findAndClick(...) || findAndClick(...) which would only execute the next findAndClick(...) if the previous returned false.
Since that option is somewhat hard to maintain, especially since you might have side effects in findAndClick(...) as well as being quite static and hard to read if you have more calls in there, you might want to use a list of function objects:
class FindAndClickExecutor {
public FindAndClickExecutor(String[] params) {...}
public boolean findAndClick() {...}
}
List<FindAndClickExecutor> faces = ...; //initialize appropriately
for( FindAndClickExecutor face : faces ) {
boolean ok2continue = face.findAndClick();
if( !ok2continue ) {
break;
}
}
Edit: since there seem to be other methods as well, you might use a more general list:
interface Executor {
boolean execute();
}
class FindAndClickExecutor implements Executor {
public boolean execute() {} // findAndClick code here, set parameters using constructor
}
class FindAndSelectOptionExecutor implements Executor {
public boolean execute() {} // findAndSelectOption code here
}
List<Executor> testCase1Sequence = ...; //initialize test case 1
List<Executor> testCase2Sequence = ...; //initialize test case 2
for( Executor ex : testCase1Sequence ) {
boolean ok2continue = ex.execute();
if( !ok2continue) {
break;
}
}
This example could also be expanded on, e.g. by using a more complex return value containing the continue flag and maybe more data (use interface here as well).
Edit 2: you could also use some scripting to define and the builder pattern to generate the list of executors for each test case.