Assign if not null or if not set in Java - java

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.

Related

Multi threaded issue with myMethod()

I came across this question and I am trying to figure out the answer.
This is the question:
Assuming a threaded environment, and without knowing anything else, what is the potential problem with myMethod()? How can we fix it in the simplest way?
What is the issue with myMethod?
public class DummyTest {
private static final String FUBAR = "fubar";
public boolean myMethod(final MyObject bar) {
if (bar.getFoo() != null) {
return bar.getFoo().equals(FUBAR);
} else {
return false;
}
}
public interface MyObject {
String getFoo();
void setFoo(String o);
}
}
You are checking bar.getFoo() twice which in multi threaded environment can have different results. MyObject is an interface which its methods can be not synchronized .
You also need to add null check for bar and you don't need null check for bar.getFoo() if you change you code (see below)
You can replace with one liner method:
return bar != null && FUBAR.equals(bar.getFoo());
Or with ternary conditional operator
return bar == null ? false : FUBAR.equals(bar.getFoo());
(In addition to bar potentially being null).
Potentially, bar.getFoo() could return different values on multiple invocations.
Only read it once; and check it for equality with FUBAR in a null-safe way:
return Objects.equals(bar.getFoo(), FUBAR);
// or
return FUBAR.equals(bar.getFoo());
Beside the obvious where bar may be null, the double call to bar.getFoo() is problematic. If we assume that other threads are running, then bar may be changed between the two calls to bar.getFoo() and return two different strings.
A solution would be to call bar.getFoo() only once and save the returned String as a local variable.
public boolean myMethod(final MyObject bar) {
if (bar == null)
return false;
String foo = bar.getFoo();
if (foo != null) {
return foo.equals(FUBAR);
} else {
return false;
}
}
Note: Even in non-multithreaded environment, bar.getFoo() may return different values for every call.

How to check multiple objects for nullity?

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

Evaluating multiple variable together in if condition

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 )
{//...}

How to pass different enums as argument?

I have some enums, all different, and I want to create a function that can find or not if a string is one of enum variable name (not sure it's really understandable).
enum MYENUM {
ONE,
TWO;
}
enum MYENUM1 {
RED,
GREEN;
}
I want to do this (this is just for the example, my enum are more complicated):
if(isInEnum(MYENUM, "one")) ...
if(isInEnum(MYENUM1, "one")) ...
isinEnum function (the code is bad, it's just for understanding):
boolean isinEnum(enum enumeration, String search) {
for(enum en : enumeration.values()){
if(en.name().equalsIgnoreCase(search)) return true;
}
return false;
}
Is this kind of thing possible?
I think not, according to what I can read on the web, but maybe someone has a solution to do this, instead of making one loop for each enum.
Here is a way using reflection...
public class EnumFinder {
public static <T extends Enum<T>> boolean isInEnum(Class<T> clazz, String name) {
for (T e : clazz.getEnumConstants()) {
if (e.name().equalsIgnoreCase(name)) {
return true;
}
}
return false;
}
public static void main(String[] argv) {
System.out.println(isInEnum(MYENUM.class, "one")); // true
System.out.println(isInEnum(MYENUM1.class, "one")); // false
}
}
Your attempt in your answer was actually very close. The only difference is that Java needs an instance of the defining class in order to answers questions about an unknown type dynamically at runtime.
This may not be the cleanest solution because it uses exceptions in the normal program flow, but it is certainly short, because it avoids the loop:
boolean isinEnum(Class<T> enumClass, String search) {
try {
Enum.valueOf(enumClass, search);
return true;
} catch (IllegalArgumentException iae) {
return false;
}
}
Your question is a bit tough to understand, but I think I get the gist of it.
You might be making things a lot tougher on yourself than necessary.
Take a look at Java's map interface / data structure (in java.util) and see if that moves you closer to your solution:
java.util Interface Map<K,V>
If not, repost with any leg-work you've done and I'll see if I can help ya' further. ;-)

Optional class-members

I import data from a XML file to use it internally. Now there is an uint value, which is (according to the XSD) not required. Now here is the question: How do map this behaviour in my class (it is unclear, if the Value is present or not, but I need to know at runtime)
Basically I see 3 solutions:
Solution 1: Use values of which we know that they are invalid to flag the Value as 'not-set':
public class Solution1 {
private int optionalVal;
public boolean isSetOptionalVal() {
return (optionalVal>=0);
}
public void setOptionalVal(int val) {
optionalVal = val;
}
public void unSetOptionalVal() {
optionalVal = -1;
}
public int optionalVal() {
if(isSetOptionalVal()) {
return optionalVal;
} else {
return -1;
}
}
}
Solution 2: Use the boxed class and set it to null if the value is 'not-set':
public class Solution2 {
private Integer optionalVal;
public boolean isSetOptionalVal() {
return (optionalVal!=null);
}
public void setOptionalVal(int val) {
optionalVal = val;
}
public void unSetOptionalVal() {
optionalVal = null;
}
public int optionalVal() {
if(isSetOptionalVal()) {
return optionalVal;
} else {
return -1;
}
}
}
Solution 3: Use an additional variable that describes the value as 'not-set':
public class Solution3 {
private int optionalVal;
private boolean optionalValSet;
public boolean isSetOptionalVal() {
return (optionalValSet);
}
public void setOptionalVal(int val) {
optionalVal = val;
optionalValSet = true;
}
public void unSetOptionalVal() {
optionalValSet = false;
}
public int optionalVal() {
if(isSetOptionalVal()) {
return optionalVal;
} else {
return -1;
}
}
}
These are my proposals to solve the issue, but I don't really like any of those.
Solution 1 seems very hacky, maybe there is somewhere a point where I can't determine the invalid value.
Solution 2 is actually the solution I am using, but I only need the additional information for some of the memeber variables, so I have either to use some variables as boxed types and some as primitive (which seems inconsistent) or I have always to use the boxed types (which I don't really like).
Solution 3 seems to be the cleanest, but here I am worried, that at some place the bool isn't set correctly, which would be a hard to find error (I already have a lot of code, and found the problem, that some elements are not set in the XML just recently)
So...what would you prefer as a solution to solve the "Optional Value"-problem - is there maybe an even better solution?
How is this problem generally handled?
I'd choose option 2, using the Integer class, and leave the conversion between int and Integer to autoboxing. The advantage of this approach is that it keeps everything concerned with your optional value in a single variable.
The first option is a magic value, and if the unused value becomes a used value later, it becomes a nightmare to maintain.
The third option means having to keep track of both the int and the boolean that keeps track of the question whether it is used. If you're going to do this, consider making it a class in and of itself... but then you might as well use Integer.
Solution 2 is by far the cleanest. That's exactly what null is for, and using primitive types for some values and wrapper types for others communicates that there's a difference - theres nothing inconsistent about it.
I'd also prefer solution 2, which is what we generally use as well.
Just a note though: your getters/setters should reflect that, i.e. they should look like this (which might actually be the case in your code but not in your post):
public void setOptionalVal(Integer val) {
optionalVal = val;
}
public Integer optionalVal() {
return optionalVal;
}
Since you already have null as the indicator whether the optional value is set or not, I'd not introduce another value (-1 in your case). If you need a default value that's most likely dependent on the user of that object.

Categories

Resources