I'm refactoring a very large method with a lot of repetition in it.
In the method there are many while loops which include:
if ( count > maxResults){
// Send error response
sendResponse(XMLHelper.buildErrorXMLString("Too many results found, Please refine your search"), out, session);
break;
I want to extract this as a method, because it happens 3 times in this one method currently, but when I do so I get an error on the break as it is no longer within a loop. The problem is that it is still necessary to break out of the while loops, but only when the maximum number of results are reached.
Any suggestions?
Suppose the method is :
public boolean test(int count, int maXResult) {
if ( count > maxResults) {
// Send error response
sendResponse(XMLHelper.buildErrorXMLString("Too many results found, Please refine your search"), out, session);
return true;
}
return false;
}
Call method from loop as :
while(testCondition) {
if (test(count, maxResults)) {
break;
}
}
This is impossible to do directly.
Most often you want to break because you have found the solution and no longer have to search. So indicate in the called function that there is/was success, for instance by returning a result or a boolean to indicate success. And if the function returns success, then break.
If it is now within a method instead of the while loop have it return a value and then break based on that.
i.e.
public bool refactoredMethod(parameters)
{
if ( count > maxResults){
// Send error response
sendResponse(XMLHelper.buildErrorXMLString("Too many results found, Please refine your search"), out, session);
return true;
}
return false;
}
Try to break the loop in the method using return;
As Thriler says you cant do it directly. You could extract part of it to the method and do something like:
if(isTooManyResults(count)) { break; }
Obviously your isTooManyResults method would need to return true if there are too many results and false otherwise
Related
Let's assume that we have a for-loop that will loop through a collection or array of Strings. In that case, I am searching for a specific keyword (ex. hey) here's how I usually achieve that:
for (String result : strings)
{
if (result == "hey")
{
// Do something with that.
break;
}
}
Now, the question arises from that code snippet is, should I place a keyword (return or break) when the if-statement returns true so the loop will not continue? If not, what will happen and what's the correct way of going about it.
Edit: What happens when you use break and return? What's the difference?
Let's put your code inside a method:
private void foo()
{
for (String result : strings)
{
if (result.equals("hey"))
{
// Do something with that.
break;
}
}
bar();
}
If you use break;, the loop will terminate and bar will be reached. If you use return, the method will terminate and bar won't be executed.
Note that comparing strings should be done using equals, == compares references and not content.
If you know the word can only be found once you can surely place an break; statement so the loop won't continue after finding the match.
If you can have more than one match and you want the if block to be executed for each of those matches you should NOT put the break statement since it will stop the execution of the loop after the first match is found.
I have a method that returns all the names of people in a LinkedList for a plane.
However even though there is a return statement in the method, I'm still getting told there is a missing return statement.
How can I work around this without putting another return statement in? Why isn't it considered valid? Does putting another return statement in change what is returned?
Any feedback is greatly appreciated.
public String check() {
for (Person person: passengers)
{
return person.getName();
}
}
Because if passengers is empty, the loop will never be entered.
If the loop is never entered, assuming the only return statement is in it, we have a serious problem, don't you think ? It's like if there were no return at all.
You need to add another return statement outside of the loop.
Also note that the return will automatically exit the method, so I don't think this is exactly what you wanted as per this sentence in your question :
I have a method that returns all the names of people in a LinkedList
for a plane.
Edit
As per your edit, here how you can return a list containing all names :
return passengers.
.stream()
.map(Person::getName)
.collect(Collectors.toList());
Note that you will need to change the signature of your method to
public List<String> check()
In answer to your question in the comments. You can only return a single object from a function. You could take another container and populate it with the names and return that. For example,
public LinkedList<String> check() {
LinkedList<String> names = new LinkedList<String>();
for (Person person: passengers) {
names.add( person.getName() );
}
return names;
}
What exactly are you trying to accomplish, here?
Currently, check will only ever return the name of the first passenger. Think about how your program flows and what you want it to do.
To answer your question, you need to have an 'escape' for every possible path in your code. Even if a certain block should always catch and return (not by definition, but just by how you think the code should flow), you need to handle the case such that that block doesn't catch and return. This can be done by either fixing the first block so that it really is a catch-all, or by simply returning or throwing an error if the first block doesn't catch.
i.e.
public boolean check() {
...
if (shouldAlwaysBeTrue) return false;
}
doesn't work because shouldAlwaysBeTrue is not true by definition.
public boolean check() {
...
if (shouldAlwaysBeTrue) return false;
return true;
}
I'm sort of confused, I guess this question is just a matter of preference, I just want to understand the difference of the following code.
if (IsRegistered() == true) ...
public boolean IsRegistered()
{
private boolean status = false;
// blah blah code here
return status;
}
vs
isRegistered = IsRegistered();
if (isRegistered)
I know both would work, I'm not being pedantic but I just want to understand so I would know my way around.
if (isRegistered() == true) ...
This is verbose since you know if it returns true it will do it, if not, it wont. So its the same as doing:
if (isRegistered()) ...
What it does, its just getting the returning boolean value from the method and checking the condition in the if statement.
Now if you wanted to check the boolean value again, you would need to re-call the method (which may have to do something complex to return that value), BUT if you assign it to a variable first and then check the condition, like this:
boolean isRegistered = isRegistered();
if (isRegistered)...
Later on the code you can just do it again without calling that method again.
if (isRegistered)... // n lines later.
hence, avoiding executing the process again.
At the end of the day, it pretty much depends on what you need to do.
When you invoke a method which has a non-void return type, the method itself resolves to a value the same way that using a variable does. You can either use that value directly or assign it to a variable and use that.
Just use:
if ( IsRegistered() )
It's the most readable code. Having a variable to "unbox" the method will not do any good; the compiler picks it up and replaces it into the control code itself in an internal optimization pass.
Also, the performance of your IsRegistered() method, when the self-optimization of machines is put aside, depends on how your "my code here" works:
source : {
private boolean status = false;
// blah blah code here
return status;
}
optimization-passed : {
return false; // When internal code does not modify "status"
preturn _status; // When internal code modifies "status"
}
I had a strange problem with Java (solved). I'm asking this because i'm curious of what's going on there.
What's the difference between:
if(Transfers.protoSendLong(output, date.getTime())){}
and simply
Transfers.protoSendLong(output, date.getTime());
The difference I see is that the 1st works and the 2nd don't :S
Is there any difference on execution?
I don't think you need to know what protoSendLong() is about to answer. If you need it, just ask.
EDIT:
You have the code of the method here. That's the most I can give you.
public static boolean protoSendLong(ObjectOutputStream output, long x) {
boolean r = false;
try {
output.writeLong(x);
r = true;
} catch (IOException ex) {
Logger.getLogger(Transfers.class.getName()).log(Level.SEVERE, null, ex);
}
return r;
}
There is no difference it all in the two snippets with respect to invoking the method. It gets invoked in both cases. If the method doesn't do what you expect in one case or another it is nothing to do with this snippet.
Since you have the function call inside if statement, we could assume that the function
Transfers.protoSendLong
return Boolean.
In the code,
if(Transfers.protoSendLong(output, date.getTime()))
{
"do something"
}
Thus, "do something" is executed only when the function "Transfers.protoSendLong" returns TRUE. If it returns false "do something" is skipped.
But in case of ,
Transfers.protoSendLong(output, date.getTime());
TRUE or FALSE maybe returned but nothing would changed the flow of code since there is no if statement or any variable to catch it.
I want to verify multiple conditions for validations. Currently, I have it set up such that in case of an error, each condition returns the error message, and an empty string in the absence of any errors. As a result, my code looks something like this:
String error = condition1(argA, argB);
if (!"".equals(error)) {
return error;
}
error = condition2(argC, argD);
.
.
.
and so on.
I wanted to know if there's a more elegant way of doing this in Java (or cofeescript)?
How about rather than having a lot of if statements you just create one method to check since if seems the check is the same for all conditions like.
public String check(String err)
{
if (!"".equals(err))
{
return err;
}
return err;
}
Now whenever you checking you just call the method
check(condition1(argA,argB));
and
check(condition2(argC,argB));
The string returned ofcause you know what to do with it.
Hope that helps