eclipse autogenerates !=null recursive calls - java

given a java code such as:
Something v = a.getB().getC().getD().getE();
Is there a way in Eclipse (templates or external plugins) to generate a safe chain call as:
if(a!=null &&
a.getB()!=null &&
a.getB().getC()!=null &&
a.getB().getC().getD()!=null &&
a.getB().getC().getD().getE()!=null){
Something v = a.getB().getC().getD().getE();
}

Have you given any thought to a try{} catch(NullPointerException e){} block? It might feel less elegant, but it will stop your code if any of the method calls fails because the previous one returned null, and it will give you the chance to give the default value if it is null.
Another option would be something like this:
Something v = /*Default Value*/ // Will be overwritten if subsequent methods succeed.
Object temp = a.getB(); // Use whatever Object type getB() returns.
if(temp != null){
temp = temp.getC();
/* If getC() returns a different type of object,
* either use a different variable or make the temp variable even broader
* (such as the generic Object type) */
if(temp != null){
temp = temp.getD();
if(temp != null){
temp = temp.getE();
if(temp != null)
v = temp;
/* If all previous calls returned something substantial,
* v will be something useful */
}//if(getE() != null)
}//if(getD() != null)
}//if(getC() != null)
}//if(getB() != null)
If you want, you could use a slightly less CPU efficient, but easier to read, version by not nesting the if statements. If all of the if statements are executed after eachother, a single null will prevent all of the next statements from executing, although its value will still be checked every time.
As far as generating these statements, I'm not really sure. That will really depend on how far in advance you can predict what new methods will be available from the Object returned by previous method calls. If you're aiming for auto-generation of code, you might be better off with my first suggestion: try-catch

Do this only if no one will read your code. Try to avoid generated code especially the one you're asking for.
getB() method is called 4 extra times, etc.
By checking for null manually you'll learn coding faster and make less bugs not relying on automatic code correction ;)

Related

Best way to check if an object is null to prepare for mapping

I’m trying to map an object to another and I’m having trouble deciding what’s the best practice to check if the object from where I want to map is null
1 -
public DTOIntIdentityDocument mapIdentityDocument(Identitydocument in) {
if (in == null) {
return null;
} else {
DTOIntIdentityDocument out = new DTOIntIdentityDocument();
out.setDocumentType(this.mapDocumentTypeÇ(in.getDocumenttype()));
out.setDocumentNumber(in.getDocumentnumber());
return out;
}
}
2 -
public DTOIntIdentityDocument mapIdentityDocument(Identitydocument in) {
DTOIntIdentityDocument out = null;
if (in != null) {
out = new DTOIntIdentityDocument();
out.setDocumentType(this.mapDocumentTypeÇ(in.getDocumenttype()));
out.setDocumentNumber(in.getDocumentnumber());
}
return out;
}
¿Any ideas on what's the best practice to do this?
Obviously, this boils down to style, thus there are no hard rules that tells us which version is "best". If all the code your team writes follows scheme 1, then that is the best code for you.
Having said that, I prefer a simple initial guard, followed by the code computing the "real" result, like this:
if (in == null)
return null;
DTOIntIdentityDocument out = new DTOIntIdentityDocument();
out.setDocumentType(this.mapDocumentTypeÇ(in.getDocumenttype()));
out.setDocumentNumber(in.getDocumentnumber());
return out;
You want to write code that is easy to read and understand. Your version one has that else block ... that actually doesn't need to be in its own block, with additional indents. On the other hand, your second snippet is using three different layers of abstraction: a simple assignment, an if-block, a simple return. That is definitely "more complex" than option 1, or the modified code I used above. But note: option 2 has its advantages, too. If you want/have to trace/log the result of that method, with option 2, you add a single trace(out) right before the return statement.
And for the record: when you go "hardcore" clean code, the method would finally read:
if (in == null)
return null;
return createDocumentFrom(in);
or something alike. Meaning: you push that code that actually creates and configures the result object into its own private method. And that method doesn't need to worry about a null parameter being passed in!
Finally: the ideal solution does not need to have to worry about null parameters. Simply because you avoid null like the plague. Not always possible, but always desirable!
if(in != null)
mapIdentityDocument(in)
public DTOIntIdentityDocument mapIdentityDocument(Identitydocument in) {
DTOIntIdentityDocument out = new DTOIntIdentityDocument();
out.setDocumentType(this.mapDocumentTypeÇ(in.getDocumenttype()));
out.setDocumentNumber(in.getDocumentnumber());
return out;
}

What is the advantage of assigning variable that is part of condition in while condition?

String var;
while((var = "abc") == "abc"){
System.out.println("In loop");
}
What is the advantage of assigning a variable while doing a check for the condition in the while loop.
In that example, there is none, but I assume you're talking about something like:
while ((var = obj.someMethod()) != null) {
// ...use var...
}
...where null is any of several marker values depending on what obj and someMethod are. For instance, using BufferedReader's readLine, you might loop through lines like this:
while ((line = reader.nextLine()) != null) {
// ...use the line...
}
This is a fairly common idiom when dealing with objects that have a method that keeps returning something useful until/unless it reaches the "end" of what it's working through, at which point it returns a marker value saying it's done (null is a common choice). The idiom is useful because it advances to the "next" thing, remembers the "next" thing, and checks for whether it's done.
But in your example, there'd be no point whatsoever. Also, it compares strings incorrectly. :-)

Refactoring an arrow head anti-pattern

I have some data that I'm querying in a single method.
It's gotten to the point where it's become the arrowhead anti-pattern.
It looks something like this:
void queryData()
{
int masterIndex = getMasterIndex();
if (masterIndex != -1)
{
byte[] pageData = getMasterPage(masterIndex);
if (pageData) != null)
{
Item1 i1 = getItem1(pageData);
Item2 i2 = getItem2(pageData);
if (i1 != null && i2 != null)
{
showResults(i1, i2);
}
}
}
}
Imagine the above but larger. More if statements and each method that is called has a decent amount of logic in it.
Now what I can do is refactor the above method so all if statements are positive and early return if true.
I feel it would be cleaner to break each query and validity check into their own class though.
Each action would inherit/implement an interface like the following:
public interface Action
{
public void run();
public boolean wasSuccessful();
}
I would create a list of the actions required and run through them one at a time.
This way it is obvious to see what logic belongs with each action.
Is this over architected? Is the above an existing pattern I don't know of yet?
Thanks in advance.
I would start off by abusing the "Extract Method" function of your IDE (if it has one) and pull out each logic branch into its own method. That way you make the code a lot more readable.
You'll probably want to start off writing a unit test first to make sure the result of your refactoring doesn't break or change the business logic of the code itself. Once you have refactored into smaller methods and are confident that the code still works as originally intended, you can then look at whether you can create classes and extract the code into those.
I wouldn't say that creating classes to have your queries and validity checks would be overengineered, as long as it makes sense and is readable. As you said, you could have a List<Action> and then loop through calling the run() method on each, then check wasSuccessful() on each and output the information as needed.
This way if you ever want to change the validation or query of a given action, you just change the class that the functionality is encapsulated in and you don't have to change your actual execution code.
Look how much cleaner it is with simply the early returns:
void queryData()
{
int masterIndex = getMasterIndex();
if (masterIndex == -1)
return;
byte[] pageData = getMasterPage(masterIndex);
if (pageData == null)
return;
Item1 i1 = getItem1(pageData);
Item2 i2 = getItem2(pageData);
if (i1 == null || i2 == null)
return;
showResults(i1, i2);
}
I think this is a better approach than creating an additional class structure.

Skip a record in LoadFunc.getNext()

I'm extending the LoadFunc. In the getNext function I'd like to skip returning a tuple under certain conditions - this way I could only load a sample of the data file. I tried returning null for the rows I don't want to return but the problem is that the method terminates after the first null Tuple is returned.
Does anyone know of a way to do this? Should I do it in a different method?
Thanks in advance.
(Assuming you mean LoadFunc in Pig ... )
I would suggest writing a new method that does what you want simply to not break the original documented use of the getNext() method.
You should look at the source for the Pig classes that extend LoadFunc and see how they implement getNext(). For example: TextLoader
From there it should be fairly trivial to do what you're trying to do.
Edit to try and offer a little more detailed help:
(This is using the TextReader as an example)
The getNext() method is reading from a RecordReader. It does this by calling RecordReader.nextKeyValue() to advance to the next record. You check to see if that's true (meaning it read a record) and if it is, you call RecordReader.getCurrentValue() to retrieve the value.
Lets say you only wanted every fifth one as a sample in getNext():
int count = 0;
Text myText = null;
whlie(myRecordReader.nextKeyValue() == true)
{
if (count == 4)
{
myText = (Text) myRecordReader.getCurrentValue();
break;
}
count++;
}
if (myText != null) // we didn't hit the end; we have a record
{
... // create the tuple
return myTuple;
}
else
return null;
(corrected my silly off-by-one mistake)

Extract Method with continue

We're refactoring a long method; it contains a long for loop with many continue statements. I'd like to just use the Extract Method refactoring, but Eclipse's automated one doesn't know how to handle the conditional branching. I don't, either.
Our current strategy is to introduce a keepGoing flag (an instance variable since we're going to want to extract method), set it to false at the top of the loop, and replace every continue with setting the flag to true, then wrapping all the following stuff (at different nesting levels) inside an if (keepGoing) clause. Then perform the various extractions, then replace the keepGoing assignments with early returns from the extracted methods, then get rid of the flag.
Is there a better way?
Update: In response to comments - I can't share the code, but here's an anonymized excerpt:
private static void foo(C1 a, C2 b, C3 c, List<C2> list, boolean flag1) throws Exception {
for (int i = 0; i < 1; i++) {
C4 d = null;
Integer e = null;
boolean flag2 = false;
boolean flag3 = findFlag3(a, c);
blahblahblah();
if (e == null) {
if (flag1) {
if (test1(c)) {
if (test2(a, c)) {
Integer f = getF1(b, c);
if (f != null)
e = getE1(a, f);
if (e == null) {
if (d == null) {
list.add(b);
continue;
}
e = findE(d);
}
} else {
Integer f = getF2(b, c);
if (f != null)
e = getE2(a, f);
if (e == null) {
if (d == null) {
list.add(b);
continue;
}
e = findE(d);
}
flag2 = true;
}
} else {
if (test3(a, c)) {
Integer f = getF2(b, c);
if (f != null)
e = getE2(a, f);
if (e == null) {
if (d == null) {
list.add(b);
continue;
}
e = findE(d);
}
flag2 = true;
} else {
if (d == null) {
list.add(b);
continue;
}
e = findE(d);
flag2 = true;
}
}
}
if (!flag1) {
if (d == null) {
list.add(b);
continue;
}
e = findE(d);
}
}
if (e == null) {
list.add(b);
continue;
}
List<C2> list2 = blahblahblah(b, list, flag1);
if (list2.size() != 0 && flag1) {
blahblahblah();
if (!otherTest()) {
if (yetAnotherTest()) {
list.add(b);
continue;
}
blahblahblah();
}
}
}
}
This is one of those fun ones where no single pattern will get you there.
I would work at it iteratively.
First I'd try to see if I couldn't use an early continue to remove one of those levels of ifs. It's much clearer code to check for a condition and return early (or in your case continue) than to have deeply nested ifs.
Next I think I'd take some of the inner chunks and see if they couldn't be extracted into a separate method. It looks like the first two big blocks (within the "if (test2(a, c)) {" and its else statement) are very similar. There is cut and paste logic that should be the same.
Finally after that stuff is cleared up, you can start looking at your actual problem--you need more classes. This entire statement is probably a three line polymorphic method in 3-5 sibling classes.
It's very close to throw-away and rewrite code, once you identify your actual classes, this entire method will vanish and be replaced with something so simple it hurts. Just the fact that it's a static utility method should be telling you something--you don't want one of those in this type of code.
Edit (After looking a little more):
There is so much here it would be really fun to go through. Remember that when you are done you want no code duplication--and I'm pretty sure this entire thing could be written without a single if--I think all your ifs are cases that could/should easily be handled by polymorphism.
Oh, and as an answer to your question of eclipse not wanting to do it--don't even TRY automatic refactoring with this one, just do it by hand. The stuff inside that first if() needs to be pulled out into a method because it's virtually identical to the clause in its else()!
When I do something like this, I usually create a new method, move the code from the if into the new method (leaving just a call to the new method inside the if), then run a test and make sure you didn't break anything.
then go line by line and check to ensure there is no difference between the if and its else code. If there is, compensate for it by passing the difference as a new variable to the method. After you're sure everything is identical, replace the else clause with a call. Test again. Chances are at this point a few additional optimizations will become obvious, you'll most likely lose the entire if by combining it's logic with the variable you passed to differentiate the two calls.
Just keep doing stuff like that and iterating. The trick with refactoring is to use Very Small Steps and test between each step to ensure nothing changed.
continue is basically an analogue of an early return, right?
for (...) {
doSomething(...);
}
private void doSomething(...) {
...
if (...)
return; // was "continue;"
...
if (!doSomethingElse(...))
return;
...
}
private boolean doSomethingElse(...) {
...
if (...)
return false; // was a continue from a nested operation
...
return true;
}
Now I must admit that I didn't quite follow your current strategy, so I might have just repeated what you said. If so, then my answer is that I can't think of a better way.
If I were faced with your situation I would look at using other refactoring techniques such as "replace conditional with polymorphism". That said you should always do one thing at a time, so if you first want to extract method you have two options:
Add the "keepGoing" flag
Throw an exception from the method
Of these two options, I think the keepGoing flag is better. I wouldn't stop refactoring after you extract the method. I am sure once you have a smaller method you will find a way to remove this flag and have cleaner logic.
I'm going to summarize the answers here, while accepting Bill K's answer as the most complete. But everyone had something good to offer, and I might use any of these approaches next time I'm faced with this sort of situation.
mmyers: Cut out the loop body, paste it into a new method and replace all the continues with returns. This worked very nicely, although it would have trouble if there were other control flow statements, like break and return, inside the loop.
Bill K: Tease it apart iteratively; look for duplication and eliminate it. Take advantage of polymorphic classes to replace the conditional behavior. Use Very Small Steps. Yes; this is all good advice, with broader applicability than just this specific case.
Aaron: Either use the keepGoing flag to replace the continue or throw an Exception. I didn't try this, but I think the Exception option is a very nice alternative, and one I hadn't considered.

Categories

Resources