Can I simplify this java if construct? It seems too verbose to me, I'd like to have it shorter.
A is persistent Object, which will be null if it's context is accessed first time. Than A is instatniated and given content, and if this fails, some backup content is given to A.
if (A == null) {
A = staticGetMethod();
if (A == null) A = new BackupAContent() { ... };
}
Update: Or you could simply remove the nesting as it will still behave the same way.
if (A == null) {
A = staticGetMethod();
}
if (A == null) {
new BackupAContent() { ... };
}
Should work:
if (A == null && (A = staticGetMethod()) == null) {
new BackupAContent() { ... };
}
Put your building logic in factory method
if (objA == null) {
objA = getAInstance();
}
encapsulate the code suggested by Charles into a method to implement Factory_method_pattern
You can use a ternary operator instead of the if statements:
a = a ? a : staticGetMethod();
a = a ? a : new BackupAContent();
That said, I'd stick with what you've got, to be honest -- except that I would add a block for the second conditional rather than putting the statement inline with it.
This is Charles Goodwin's code with a slight change:
if (A == null && (A = staticGetMethod()) == null) {
new BackupAContent() { ... };
}
I used an AND instead of an OR
I think this is the best way to do it:
if(A == null)
{
if((A = staticGetMethod()) == null) A = new BackupAContent() { ... };
}
Related
I am facing an issue that confused me always while checking the source code in JDK.
Below is code snippet from ConcurrentHashMap.
Why don't to use table varible directly? but rather to assign it to the t local var. is this a recommended style in java?
public boolean containsValue(Object value) {
if (value == null)
throw new NullPointerException();
Node<K,V>[] t;
if ((**t** = **table**) != null) {
Traverser<K,V> it = new Traverser<K,V>(**t**, **t**.length, 0, t.length);
for (Node<K,V> p; (p = it.advance()) != null; ) {
V v;
if ((v = p.val) == value || (v != null && value.equals(v)))
return true;
}
}
return false;
}
If you're running multiple threads then table might be changed by another thread and become null partway through the method. But t cannot be changed elsewhere, because it only exists inside this method. This is a way of avoiding a possible exception.
I am new to Java. I am facing an issue now in which I couldn't find the easiest and cleanest way of solving it.
Suppose I have 3 parameters(string) passed to a function(could be a Hashmap too).I want to check if individual variable or combination of variables is not Null and act accordingly.
For example one way to do this is using if-else this way
if(a!=null && b == null && c == null) {
//doSomething
}
else if(a==null && b!= null && c == null ) {
//doSomething
}
else if(a==null && b0= null && c != null) {
//doSomething
}
......
//Similarly combination of two variables
if(a!=null && b != null && c == null) {
//doSomething
}
else if(a!=null && b== null && c != null) {
//doSomething
}
else if(a==null && b!= null && c != null) {
//doSomething
}
......
//and so on
//Similarly combination of three variables
if(a!=null && b != null && c != null) {
//doSomething
}
....
How to achieve this kind of situation. I found similar question, but didn't make the code clean. Any help will be appreciated
Write these utility functions and you can compare n terms easily.
public static boolean areAllNull(Object... objects) {
return Stream.of(objects).allMatch(Objects::isNull);
}
public static boolean areAllNotNull(Object... objects) {
return Stream.of(objects).allMatch(Objects::nonNull);
}
you can use these functions for n comparisons.
if(areAllNotNull(a) && areAllNull(b,c)) {
//doSomething
}
else if(areAllNotNull(b) && areAllNull(a,c)) {
//doSomething
}
else if(areAllNotNull(c) && areAllNull(b,a)) {
//doSomething
}
This is my solution. Note, that you have multiple if...else in one single method. And then you add doSomething. This is going to be terrible to ready and later to realize.
What about to move one single condition into separate method and name it with relative name. Then, lets encapsulate it into Consumer and all of it into a predefined list. Later, if your doSomething will be huge, then you can move from single method to single class, not modifying client code.
This is class, to collect required variable for conditions:
final class Data {
private final String a;
private final String b;
private final String c;
}
Then define one Consumer per on if statement:
Consumer<Data> wonderfulConsumer = data -> {
if (a != null && b == null && c == null) {
// do something for wonderful consumer
}
};
Consumer<Data> badLuckConsumer = data -> {
if (a == null && b != null && c == null) {
// do something for bad luck consumer
}
};
Note, all these consumers could be modified separately (even be in the different classes).
Then in the client code, define list of all known consumers: List<Consumer<Data>> consumers = Arrays.asList(wonderfulConsumer, badLuckConsumer).
And finally your method will be like this and you do not need to change it when you decide to modify or add consumers.
Data data = new Data(a, b, c);
consumers.forEach(consumer -> consumer.accept(data));
If I had to do this , i will do it in the same way that you have done.
but if you dont like that and if you think it is not readable you can do it in this way, i expect lot of negative comments to this answer because this is a bad solution.
public static void yourMethod(Object a,Object b,Object c)
{
int evaluation = howManyNotNull(a,b,c);
if(evaluation == 0) // all are nulls
{
// your code
}
else if(evaluation == 1) // only one is not null
{
if(a!=null)
{
}
else if(b!=null)
{
}
else
{
// c not null
}
}
else if(evaluation == 2) // two variables are not null but other one is null
{
if(a==null)
{
}
else if(b == null)
{
}
else
{
// c is null, a and b not null
}
}
else
{
// all abc not null
}
}
private static int howManyNotNull(Object a, Object b, Object c)
{
return (a==null?0:1) + (b==null?0:1) + (c==null?0:1);
}
There is extended version of this , assign 3 prime values for a, b , c (example :a=2,b=3,c=5), then use a supportive method like this
private static int convertAvailabilityToInt(Object a, Object b, Object c)
{
return (a==null?1:2) * (b==null?1:3) * (c==null?1:5);
}
if the answer is 1 ,then all are not null .
You can use for example a 3 digit string simulating 3 flags.
You first set it to "000".
Then you check each variable for null, if it is not you will replace the 0 with 1.
Then you could use switch cases to treat each case.
You are doing everything right but you have to remember that primitive data types cannot be null. For example string is not null, but empty string "", or int cannot be null, its by default sets to 0. In conclusion Objects like Map , ArrayList or Integer.. you can check for null, but primitive data types cannot be null, so you cannot check them for it. For deeper understanding just learn about primitive and advanced data types.
I hope I got your problem right :)
Hi I have written a little function like
public void foo(MyClassA paraA) {
if (paraA == null) return;
MyClassB paraB = doSomeStuff(paraA);
if (paraB == null) return;
MyClassC paraC = doMoreStuff(paraB);
if (paraC == null) return;
....
}
The above fails fast and is nice to read (i.e. the intention to return on null values is clear). But now instead of simply returning, I want to do some error logging, so I changed to
public void foo(MyClassA paraA) {
if (paraA == null) {doLog(); return;}
MyClassB paraB = doSomeStuff(paraA);
if (paraB == null) {doLog(); return;}
MyClassC paraC = doMoreStuff(paraB);
if (paraC == null) {doLog(); return;}
....
}
The above is also clean and easy to read, but I have to repeat doLog() a couple of times. So I change again to
public void foo(MyClassA paraA) {
if (paraA != null) {
MyClassB paraB = doSomeStuff(paraA);
if (paraB != null) {
MyClassC paraC = doMoreStuff(paraB);
if (paraC != null) {
....
return;
}
}
}
doLog();
}
The above calls doLog() only just once but I ended with some deeply-nested if statements, which are very ugly and hard to read. So how do I keep the same cleanliness like before and have doLog() just once? Note that returning something else rather than void for foo() is not allowed. And I also read that using try/catch as oppose to null check is an anti-pattern.
If I am to try, I want to write something like
public void foo(MyClassA paraA) {
while(true) {
if (paraA == null) break;
MyClassB paraB = doSomeStuff(paraA);
if (paraB == null) break;
MyClassC paraC = doMoreStuff(paraB);
if (paraC == null) break;
....
return;
}
doLog();
}
The above fulfills all my needs(fail fast, clean, no nested if), but is the use of the while loop here an anti-pattern as the while loop here is never meant to run more than once?
Java has a nifty labeled break construct that might help you, here.
public void foo(MyClassA paraA) {
block: {
if (paraA == null) { break block; }
MyClassB paraB = doSomeStuff(paraA);
if (paraB == null) { break block; }
MyClassC paraC = doMoreStuff(paraB);
if (paraC == null) { break block; }
...
return;
}
doLog();
}
If you used polymorphism better, you could do this:
public void foo(MyInterface para) {
while (para != null) {
para = para.doStuff();
}
doLog();
}
If you absolutely can't use polymorphism like that, use a dispatcher.
But I've seen this before, and it looks like a state machine. Give "java enum state machine" a search. I have a feeling that's what you're really trying to do.
Do you think that this is clean
public void foo(MyClassA paraA) {
MyClassB paraB = paraA != null?doSomeStuff(paraA):null;
MyClassC paraC = paraB != null?doMoreStuff(paraB):null;
if (paraC != null) {
....
}
doLog();
}
IMHO your second code snippet is what ypu should do.
Do not try to make your code short. This is an antipattern.
if (a==null) {
log("Failed in step a");
return;
}
B b = a.doSomething();
is very fast to read and understand. You save nothing by compressing this code. Zero. Nada. Leave it to Hotspot VM, and focus on making code understandable. "if null then log return" is a classic, well understood and accepted pattern.
It had become popular to try to make code "readable" with lambda antipatterns like this:
B b = ifNullLog(a, () -> a.doSomething())
where
T ifNullLog(Object guard, Function<T> func) {
if (guard == null) { doLog(); return null; }
return func.run();
}
but IMHO this is a total antipattern. In fact, it is a best practise to even require braces for every if, else, for, while to make it easy to insert such a log statement without risking to break the code.
Code like your first snippet:
if (a == null) return;
are dangerous. Look at various bugs like Apples SSL disaster
If someone adds doLog without noticing the missing brackets, the function will always return null. The apple SSL bug (or was it heartbleed?) esdentially was a
if (a==null)
return;
return;
B b = a.doSomething();
See how subtle the bug is? You Java compiler will fortunately warn you if it's about unreachable code - it will not necessarily warn you otherwise... by always using brackets and well formatted code such bugs can easily be avoided. Format code to avoid errors, not for aestetics.
It is also well acceptable to use return codes. Just don't make success default (see heartbleed again).
Code c = execute(a);
if (c != Code.SUCCESS) {
doLog(c);
return;
}
where
Code execute(A a) {
if (a == null) { return Code.FAILED_A_NULL; }
B b = a.doSomething();
if (b == null) { return Code.FAILED_B_NULL; }
...
return Code.SUCCESS;
}
A classic use case of "return", another good pattern.
I have a situation in my code where I make about 5 chained get calls, and any of those get calls could return a null value. I wish it didn't have to be that way, but that's just how the service I'm consuming returns the object I request, so I have to deal with it.
Originally, my code looked something like this:
String firstDomain = book.getBookImages().getDomains().getDefaults().getDomain().get(0);
Unfortunately, that line is prone to null pointers and arraylist out of bounds exceptions. I know I'm going to have to check for null pointers, but I'm trying to decide
A. The most efficient code to do so
and
B. The best looking code to do so
One option is to assign a ton of references and then check for nulls. Something like this:
BookImages bImages = book.getBookImages();
Domains domains = null;
Defaults defaults = null;
List<String> domain = null;
String firstDomain = null;
if (bImages != null) {
domains = bImages.getDomains();
if (domains != null) {
defaults = domains.getDefaults();
if (defaults != null) {
domain = defaults.getDomain();
if (domain != null && domain.size() > 0) {
firstDomain = domain.get(0);
}
}
}
}
if (firstDomain == null) {
throw new IncompleteBookException("The book was incompletely attributed.");
}
I think that's pretty efficient, but it bothers me how many lines it is. It more than doubles the length of the method it is a part of.
This is the other alternative I can think of:
if (book.getBookImages() == null || book.getBookImages().getDomains() == null || book.getBookImages().getDomains().getDefaults() == null || book.getBookImages().getDomains().getDefaults().getDomain() == null || book.getBookImages().getDomains().getDefaults().getDomain().size() < 1 || book.getBookImages().getDomains().getDefaults().getDomain().get(0) == null) {
throw new IncompleteBookException("The book was incompletely attributed.");
}
I like the fact that that's only three lines, even if one is pretty darn ridiculous, but I'm not sure if Java's runtime or compiler would optimize away those repetitive method calls.
I'm also open to other, better solutions. Does anyone know if one or the other of those options would perform better than the other, or is this such a micro-optimization that it's foolish to even bother thinking about it, and I should just use whichever looks nicer to me? I may have to do this many times for different things.
To follow your second approach, you can apply this:
if ((bImages=book.getBookImages()) == null
|| (domains=bImages.getDomains()) == null
|| (defaults=domains.getDefaults()) == null
|| (domain=defaults.getDomain()) == null
|| domain.size() < 1
|| (firstDomain=domain.get(0)) == null) {
throw new IncompleteBookException("The book was incompletely attributed.");
} else {
//here you can use the firstDomain variable, that is set with the correct value
}
This is better because you avoid multiple (useless) identical calls, and you already set the correct value in the variable firstDomain (of course, only if there is nothing null and so on...)
As Szymon pointed out you should not call same method twice.
To make your original solution slightly more readable by combining all your nested null checks into one:
BookImages bImages = null;
Domains domains = null;
Defaults defaults = null;
List<String> domain = null;
String firstDomain = null;
if ((bImages = book.getBookImages()) != null
&& (domains = bImages.getDomains()) != null
&& (defaults = domains.getDefaults()) != null
&& (domain = defaults.getDomain() != null
&& domain.size() > 0) {
firstDomain = domain.get(0);
}
You should not worry about the length of the code too much if the longer code is correct and shorter incorrect. The goal of programming is not writing the shortest possible code (with the exception of some competitions, etc).
Your first (longer) way is correct, even if a bit longish.
The second way will make repeated calls to the same method. This is something you probably want to avoid - it may have undesirable effects and is worse for performance.
Try using a boolean method; they tend to make logic a lot simpler and much more legible; for example, I would do this:
public boolean isCompletelyAttributed(BookImages bImages) {
if (bImages == null) return false;
if (bImages.getDomains() == null) return false;
if (bImages.getDomains().getDefaults() == null) return false;
if (bImages.getDomains().getDefaults().getDomains() == null) return false;
return bImages.getDomains().getDefaults.getDomains.size() > 0;
}
Then you call
if (!isCompletelyAttributed(book.getImages())) {
throw new IncompleteBookException("The book was incompletely attributed.");
}
I also recommend that you use Nicola or kiruwka's solution in your boolean method. I was not aware that you could reassign variables while doing logic on them, but that appears to be an elegant solution.
Here's a short-ish way to do it. But hey, I don't know the specifics of what you're building and whether this works for you.
try {
String firstDomain = book.getBookImages().getDomains().getDefaults().getDomain().get(0);
// operate on firstDomain
} catch (NullPointerException e) {
throw new IncompleteBookException("The book was incompletely attributed.");
} catch (IndexOutOfBoundsException e) {
throw new IncompleteBookException("The book was incompletely attributed.");
}
I've heard that people are concerned with the performance of something like this, because the VM will have to fill in a stack trace for the NullPointerException. In this case, you'll already be doing a comparable operation for the IncompleteBookException anyway.
I am having two profiles say SignProfile and ValidationProfile. These profiles can be more than 1, say
SignProfile.size >1 and ValidationProfile.size>1
Now there is a piece of code which I have to execute whenever SignProfile and ValidationProfile are not null and I need to loop through these profiles too if they are more than one for both Sign and Validation.
I am using
List<SignProfile> SP = new ArrayList<>;
List<ValidationProfile> Vali = new ArrayList<>;
while SP_interator.hasnext
{
while Vali_interator.hasnext
{
// do something
}
// Piece of code
}
Now the problem I am facing is that sometimes SignProfile comes null, but ValidationProfile is not null. So as per above code, the intended piece of code is not executed.
Could someone please guide me? Shall I use some other collection?
If you're on Java 5 or higher, you can use the foreach syntax:
List<SignProfile> signProfileList = new ArrayList<>;
List<ValidationProfile> validationProfileList = new ArrayList<>;
if(signProfileList != null) {
for(SignProfile sp : signProfileList) {
// you can work with the sp variable here, which represents the current item from signProfileList
if(validationProfileList != null) {
for(ValidationProfile vp : validationProfileList) {
// you can work with vp variable here, which represents the current item from validationProfileList
}
}
}
}
Note: I've renamed some of your variables to make the code a little clearer.
By the way, are you sure you want these nested? They don't seem to relate to eachother.
Is this what you mean?
if (signProfiles != null && validationProfiles != null) {
for (SignProfile signProfile : signProfiles) {
//do something with signProfile
}
for (ValidationProfile validationProfile : validationProfiles) {
//do something with validationProfile
}
}
Or the nested version...
if (signProfiles != null && validationProfiles != null) {
for (SignProfile signProfile : signProfiles) {
//do something with signProfile
for (ValidationProfile validationProfile : validationProfiles) {
//do something with validationProfile, and signProfile?
}
}
}