I am trying to optimize this code. The only optimization I can think of is to a return or break statement after applyOfferChanges(...) inside the second if condition.
Any ideas?
void applyFavoriteChangesToMerchantStore(){
List<Merchant> favoriteMerchantsList = FavoriteMerchantStore.getInstance().getFavoriteMerchantsList();
if(favoriteMerchantsList != null && !favoriteMerchantsList.isEmpty()) {
List<Merchant> storeMerchantList = MerchantStore.getInstance().getMerchantList();
for (Merchant storeMerchant : storeMerchantList) {
for (Merchant favoriteMerchant: favoriteMerchantsList){
if(TextUtils.equals(storeMerchant.getId(), favoriteMerchant.getId())){
//merchant match found
//set merchant favorite status
storeMerchant.setFavoriteMerchant(favoriteMerchant.getFavoriteMerchant());
//set offer favorite status
applyOfferChanges(favoriteMerchant.getOffferList(),
storeMerchant.getOffferList());
}
}
}
}
}
It all depends on things you haven't shown us. How big are the lists, what exactly does TextUtils.equals? Assuming, it's android.text.TextUtils, the answer is clear: Instead of two nested loops (complexity O(m*n)), use a HashMap (complexity O(m+n)).
Instead of
for (Merchant storeMerchant : storeMerchantList) {
for (Merchant favoriteMerchant: favoriteMerchantsList) {
if(TextUtils.equals(storeMerchant.getId(), favoriteMerchant.getId())) {
....
}
do
Map<String, Merchant> favoriteMerchantMap = new HashMap<>();
for (Merchant favoriteMerchant : favoriteMerchantsList) {
favoriteMerchantMap.put(favoriteMerchant.getId(), favoriteMerchant));
}
for (Merchant storeMerchant : storeMerchantList) {
Merchant favoriteMerchant = favoriteMerchantMap.get(storeMerchant.getId());
if (favoriteMerchant != null) {
....
}
I think you could optimize this with java-8.
If I'm not mistaken, your code does not set favorites to null if they cannot be found anymore.
This should do the same as your original code, but in a more java-8 way:
void applyFavoriteChangesToMerchantStore(){
// take list of favorite merchants
List favoriteMerchantsList = FavoriteMerchantStore.getInstance().getFavoriteMerchantsList();
// if any favorites found, we gotta do something with them
if(favoriteMerchantsList != null && !favoriteMerchantsList.isEmpty()) {
// take list of all merchants
List<Merchant> storeMerchantList = MerchantStore.getInstance().getMerchantList();
// convert those into a map with the ids as keys
Map<String, Merchant> storeMap = storeMerchantList.stream().collect(Collectors.toMap(Merchant::getId, merchant -> merchant));
// set the favorite for each merchant
favoriteMerchantsList.forEach(favoriteMerchant -> {
// if each favorite is guaranteed to be in the list of storeMerchantList, this causes no null result
Merchant storeMerchant = storeMap.get(favoriteMerchant.getId());
//set merchant favorite status
storeMerchant.setFavoriteMerchant(favoriteMerchant.getFavoriteMerchant());
//set offer favorite status
applyOfferChanges(favoriteMerchant.getOffferList(), storeMerchant.getOffferList());
});
}
}
If you want to reset (set to null) the merchants currently matching no favorites, your code could look like this:
void applyFavoriteChangesToMerchantStore(){
// take list of favorite merchants
List favoriteMerchantsList = FavoriteMerchantStore.getInstance().getFavoriteMerchantsList();
Map<String, Merchant> favMap = null;
if(favoriteMerchantsList == null) {
// if no favorites found, creating an empty map
favMap = new HashMap<>();
} else {
// convert list into a map with the ids as keys
favMap = favoriteMerchantsList.stream().collect(Collectors.toMap(Merchant::getId, merchant -> merchant));
}
// take list of all merchants
List<Merchant> storeMerchantList = MerchantStore.getInstance().getMerchantList();
// set the favorite for each merchant
storeMerchantList.forEach(storeMerchant -> {
if (favMap.containsKey(storeMerchant.getId()))
{
// get the favorite
Merchant favoriteMerchant = favMap.get(storeMerchant.getId());
//set merchant favorite status
storeMerchant.setFavoriteMerchant(favoriteMerchant.getFavoriteMerchant());
//set offer favorite status
applyOfferChanges(favoriteMerchant.getOffferList(), storeMerchant.getOffferList());
} else {
//set merchant favorite status
storeMerchant.setFavoriteMerchant(null);
// cannot call applyOfferChanges, because no favoriteMerchant (or change this as you wish)
}
});
}
}
Nothing of this is tested though, I hope they work, feel free to respond, if it helped.
Related
I am using an example of recently released Google's People API from here. I have extended a sample a bit to display additional information about the contact such as an email address and a phone number. The code that should do the job is presented below.
public class PeopleQuickstart {
...
public static void getPersonInfo(Person person){
// Get names
List<Name> names = person.getNames();
if(names != null && names.size() > 0) {
for(Name personName: names) {
System.out.println("Name: " + personName.getDisplayName());
}
}
// Get email addresses
List<EmailAddress> emails = person.getEmailAddresses();
if(emails != null && emails.size() > 0) {
for(EmailAddress personEmail: emails) {
System.out.println("Email: " + personEmail.getValue());
}
}
// Get phone numbers
List<PhoneNumber> phones = person.getPhoneNumbers();
if(phones != null && phones.size() > 0) {
for(PhoneNumber personPhone: phones){
System.out.println("Phone number: " + personPhone.getValue());
}
}
}
public static void main(String [] args) throws IOException {
People service = getPeopleService();
// Request 120 connections.
ListConnectionsResponse response = service.people().connections()
.list("people/me")
.setPageSize(120)
.execute();
// Display information about your connections.
List<Person> connections = response.getConnections();
if (connections != null && connections.size() > 0) {
for (Person person: connections){
getPersonInfo(person);
}
} else {
System.out.println("No connections found.");
}
}
}
I am testing this program with my contact list and I can successfully obtain a list of people along with the name fields. However, I cannot get values for email addresses and phone numbers (lists are always null), although I do have these values set in my contact list (verified through Gmail->Contacts). What am I missing?
Ok, problem solved. It looks like Google's documentation is a bit misleading (well, it has just been released;)). When I try to fetch my contacts using people.connections.list (see here) there are several query parameters that can be set. However, for the requestMask parameter it is stated that "Omitting this field will include all fields" which is not the case (at least did not work for me). Therefore, one has to explicitly specify which fields to be returned in the response. The modified code is given below. I wish Google people would clarify this point a bit.
public class PeopleQuickstart {
...
public static void main(String [] args) throws IOException {
People service = getPeopleService();
// Request 120 connections.
ListConnectionsResponse response = service.people().connections()
.list("people/me")
.setPageSize(120)
// specify fields to be returned
.setRequestMaskIncludeField("person.names,person.emailAddresses,person.phoneNumbers")
.execute();
// Display information about a person.
List<Person> connections = response.getConnections();
if (connections != null && connections.size() > 0) {
for (Person person: connections){
getPersonInfo(person);
}
} else {
System.out.println("No connections found.");
}
}
}
I recently started working on an app that does a request to a server and gets a json response.
The "thing" functioned beautifully until i had to implement new stuff in the list and now i have a hard time to fix it.
Any help is very appreciated:
class RemoteConfig
{
// names and type must match what we get from the remote
String[] username;
ArrayList<accDetails> in_groups;
String[] in_groups_sorted;
class accDetails
{
int group_id;
String group_label;
Boolean _is_system;
}
This is just a part of how the class starts, and here is how the json reponse looks like:
{
"username":[
"mike"
],
"in_groups":[
{
"group_id":2,
"group_label":"All users",
"_is_system":true
},
{
"group_id":4372,
"group_label":"Privileged User",
"_is_system":false
},
{
"group_id":4979,
"group_label":"Supervisor",
"_is_system":false
}
]
}
The problem that i encounter now, is that i have no idea on how to split the in_groups array list and get into String[] in_groups_sorted the value of Group_label if the _is_system value is false.
Any help is highly appreciated.
Thank you,
Mike
After checking the responses, the cleanest and simplest was the one provided by Abbe:
public String[] groupSettings()
{
String[] levels = new String[] {};
if (remoteConfig != null && remoteConfig.in_groups != null){
for (accDetails ad: remoteConfig.in_groups)
{
if (!ad._is_system) {
levels = ArrayUtils.addAll(levels, ad.group_label); ;
}
}
}
return levels;
}
From your question, I suppose the JSON is already parsed and stored in the in_groups field of RemoteConfig class. And you just need to filter the information you need to populate the in_group_sorted field.
Add the following to the RemoteConfig class:
public initGroupSorted() {
// Temporary list, since we don't know the size once filtered
List<String> labels = new ArrayList<>();
for (accDetails ad : in_groups) {
if (ad._is_system) {
groups.add(ad.group_label);
}
}
in_group_sorted = labels.toArray(new String[labels.size()]);
}
if you donĀ“t want to change the way you parse your JSON, you could always do this:
Let accDetails implement Comparable and then use Collections.sort passing in_groups.
if you really want the String[] you could always iterate over in_groups, add to in_groups_sorted and then using Arrays.sort
Mike, let me give you something that should get you going. From your question i got the feeling that your problem was on how to parse the JSON, so before you go write your own parser, consider the following piece of code that i just wrote:
public void createObjects(String rawJSON) {
try {
JSONObject object = new JSONObject(rawJSON);
JSONArray username = object.getJSONArray("username");
JSONArray inGroups = object.getJSONArray("in_groups");
RemoteConfig config = new RemoteConfig();
config.in_groups = new ArrayList<>();
config.username = username.getString(0);
for (int i = 0; i < inGroups.length(); i++) {
JSONObject group = inGroups.getJSONObject(i);
if (!group.getBoolean("_is_system")) {
accDetails details = new accDetails();
details.group_id = group.getInt("group_id");
details.group_label = group.getString("group_label");
details._is_system = false;
config.in_groups.add(details);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
Here is a Java 8 Solution using Stream's filter,sorted, and map methods:
//ArrayList<accDetails> in_groups is already populated
Stream<accDetails> tempStream= in_groups.stream().filter(p -> p._is_system == false);
tempStream= tempStream.sorted((accDetails o1, accDetails o2) -> o1.group_label.compareTo(o2.group_label));
String[] in_groups_sorted = tempStream.map(s -> s.group_label).toArray(String[]::new);
Separated the calls for visibility, but they can be a one liner:
String[] in_groups_sorted = in_groups.stream().filter(p -> p._is_system == false).sorted((accDetails o1, accDetails o2) -> o1.group_label.compareTo(o2.group_label)).map(s -> s.group_label).toArray(String[]::new);
I have an ArrayList of custom made Users. The list is already sorted by manager.My goal is to go through the list by manager and add each user to the body of an email depending on their expiration date.
A User is basically built like this from the database. All necessary accessors/mutators are present:
id|fName|lName|...|manager
Go through the users and notify the manager if the user is expiring:
To: Manager
Expiring in 10 days
<User>
<User>
Expiring in 30 days
<User>
StringBuilder body = new StringBuilder();
ArrayList<Users> contractors;
Date today = cal.getTime();
...
if(contractors != null && contractors.size() > 0){
for(int i = 0; i < contractors.size(); i++){
if(i+1 > contractors.size()){
//do something to avoid outOfBounds and still access last item in the list
}else{
if (contractors.get(i+1).getManager() != null){
if(manager.equals(contractors.get(i+1).getManager())){
if(today.compareTo(contractor.getExpiration()){
//build body of email
}
}
}
sendEmail(manager, body.toString());
}else{
//new manager
body.equals(""); // reset email for next run
}
}
After the email is sent I want to move on to the next set of users based on manager. My problem is that I'm having trouble with the logic behind traversing the array by manager and then resetting everytime for each new manager. I'm thinking that I need another for loop?
What's the best way to do this? thanks
Edit
When implemented this way:
I would do it something like this:
if (contractors != null) {
String currentManager = null;
for (User contractor : contractors) {
String contractorManager = contractor.getManager();
if (!contractorManager.equals(currentManager) {
// a new manager
if (currentManager != null) {
sendEmail(body.toString());
body.setLength(0);
}
currentManager = contractorManager;
}
//build body of email ...
}
// send the email for the last manager
sendEmail(body.toString());
}
Iterate the list of Users and add them to a Map keyed by manager with a Set of employees per manager. Something like,
if (contractors != null && contractors.size() > 0) {
Map<String, Set<Users>> map = new HashMap<>();
for (Users contractor : contractors) {
String manager = contractor.getManager();
if (manager == null) {
manager = contractor.getName();
}
Set<Users> employees = map.get(manager);
if (employees == null) {
employees = new HashSet<>();
map.put(manager, employees);
}
employees.add(contractor);
} // now you can iterate the keySet and then each manager's employees like
for (String manager : map.keySet()) {
Set<Users> employees = map.get(manager);
for (Users u : employees) {
// ...
}
}
}
You should go for a "foreach" loop on contractors, more info here
another example here
If they are already sorted, you can take this approach (I'm using "ManagerObject" to represent the return type of Users.getManager() - replace with the actual class name):
StringBuilder body = new StringBuilder();
ManagerObject currentManager = null;
for (Users contractor : contractors) {
if (currentManager != null && !(contractor.getManager().equals(currentManager)) {
sendEmail(body.toString());
body.equals("");
}
currentManager = contractor.getManager();
// Add stuff to the body for this contractor
}
If the call to Users.getManager() is computationally expensive for some reason, this can be rejiggered to only set the currentManager upon a change in value
Here i'm able to get User Screen names and printing with the below code,but how can i sort those name alphabatically.
Twitter twitter = (Twitter) request.getSession().getAttribute("twitter");
String name = (String) request.getSession().getAttribute("name");
long cursor = -1;
IDs ids = twitter.getFollowersIDs(name, cursor);
do {
for (long id : ids.getIDs()) {
User user = twitter.showUser(id);
out.println(user.getName());
}
} while ((cursor = ids.getNextCursor()) != 0);
This is my code where i'm getting names,how can i sort names.Thank for your help.
Actually a Comparator may be more than you need, I got mixed up with your previous question.
You can simply collect the names themselves in a list and then sort, e.g.:
...
final List<String> names = new LinkedList<String>();
do {
for (...) {
...
names.add(user.getName());
}
} while (...);
Collections.sort(names)
If you inspect names, it will now be sorted.
I have a java code in which there are multiple return statements in a single method. But for code cleaning purpose, I can have only one return statement per method. What can be done to overcome this.
Here is a method from my code:-
public ActionForward login(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
// Kill any old sessions
//request.getSession().invalidate();
DynaValidatorForm dynaform = (DynaValidatorForm)form;
// validate the form
ActionErrors errors = form.validate(mapping, request);
if(!errors.isEmpty()) {
this.saveErrors(request, errors);
return mapping.getInputForward();
}
// first check if token is set
if(!isTokenValid(request, true)) {
String errmsg="There was a problem with your login. Please close your browser then reopen it and try again. Make sure to click the Login button only ONCE.";
request.setAttribute("errormessage", errmsg);
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
// check the form for input errors
String errmsg = checkInput(form);
if (errmsg != null) {
request.setAttribute("errormessage", errmsg);
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
// no input errors detected
String resumekey = null;
// check for valid login
ObjectFactory objFactory = ObjectFactory.getInstance();
DataAccessor dataAccessor = objFactory.getDataAccessor();
request.setCharacterEncoding("UTF-8");
String testcode = dynaform.getString("testcode").trim();
String studentname = dynaform.getString("yourname").trim();
String password = dynaform.getString("password").trim();
// 4/3/07 - passwords going forward are ALL lower case
if (!CaslsUtils.isEmpty(password)) {
password = password.toLowerCase();
}
try{
resumekey = new String(studentname.getBytes("ISO-8859-1"),"UTF-8");
} catch (Exception e) {
log_.error("Error converting item content data to UTF-8 encoding. ",e);
}
String hashWord = CaslsUtils.encryptString(password);
// Make sure this is short enough to fit in the db
if (hashWord.length() > ConstantLibrary.MAX_PASSWORD_LENGTH) {
hashWord = hashWord.substring(0, ConstantLibrary.MAX_PASSWORD_LENGTH);
}
Login login = dataAccessor.getLogin(testcode, hashWord, false);
if (login == null || !login.getUsertype().equals(Login.USERTYPE_SUBJECT)) {
request.setAttribute("errormessage", "Incorrect test code or password.");
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
// Check if the login has expired
if (login.getLoginexpires() != null && login.getLoginexpires().before(new Date())) {
request.setAttribute("errormessage", "Your login has expired.");
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
// Check if the password has expired
if (login.getPasswordexpires() != null && login.getPasswordexpires().before(new Date())) {
request.setAttribute("errormessage", "Your login password has expired.");
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
HttpSession session = request.getSession();
session.setAttribute(ConstantLibrary.SESSION_LOGIN, login);
session.setAttribute(ConstantLibrary.SESSION_STUDENTNAME, studentname);
List<Testtaker> testtakers = null;
try {
//invalidate the old session if the incoming user is already logged in.
synchronized(this){
invalidateExistingSessionOfCurrentUser(request, studentname, testcode);
testtakers = dataAccessor.getTesttakersByResumeKey(studentname, login);// Adding this code to call getTesttakersByResumeKey instead of getTesttakers to improve the performance of the application during student login
}
} catch (Exception e) {
log.error("Exception when calling getTesttakers");
CaslsUtils.outputLoggingData(log_, request);
throw e;
}
session = request.getSession();
if(testtakers!=null)
{
if(testtakers.size() == 0) {
// new student -> start fresh
log_.debug("starting a fresh test");
// if this is a demo test, skip the consent pages and dump them directly to the select test page
if (login.getTestengine().equals(Itemmaster.TESTENGINE_DEMO)) {
return mapping.findForward("continue-panel");
}
}
// send them to fill out the profile
// check for custom profiles
String[] surveynames = new String[4];
List<Logingroup> logingroups = dataAccessor.getLoginGroupsByLogin(login.getLoginid());
for(Logingroup logingroup : logingroups) {
Groupmaster group = logingroup.getGroupmaster();
log_.debug(String.format("group: {groupid: %d, grouptype: %s, groupname: %s}", new Object[] {group.getGroupid(), group.getGrouptype(), group.getName()}));
Set<Groupsurvey> surveys = group.getGroupsurveys();
if(surveys.size() > 0) {
// grab the first (and only) one
Groupsurvey survey = surveys.toArray(new Groupsurvey[0])[0];
if(group.getGrouptype().equalsIgnoreCase(Groupmaster.GROUPTYPE_CLASS)) {
surveynames[0] = survey.getSurveyname();
} else if (group.getGrouptype().equalsIgnoreCase(Groupmaster.GROUPTYPE_SCHOOL)){
surveynames[1] = survey.getSurveyname();
} else if (group.getGrouptype().equalsIgnoreCase(Groupmaster.GROUPTYPE_DISTRICT)){
surveynames[2] = survey.getSurveyname();
} else if (group.getGrouptype().equalsIgnoreCase(Groupmaster.GROUPTYPE_STATE)){
surveynames[3] = survey.getSurveyname();
}
}
}
// match the most grandular survey
for(int i=0; i < surveynames.length; ++i) {
if(surveynames[i] != null) {
saveToken(request);
return mapping.findForward("student-profile-"+surveynames[i]);
}
}
// no custom profile, send them to the default
saveToken(request);
return mapping.findForward("student-profile");
}
// get the set of availible panels
Set<Panel> availiblePanels = dataAccessor.getAvailiblePanels(login, studentname);
if(availiblePanels.size() == 0) {
// no panels availible. send to all done!
log_.debug(String.format("No panels availible for Login:%s with resumekey:%s", login.toString(), studentname));
session.setAttribute("logoutpage", true);
resetToken(request);
return mapping.findForward("continue-alldone");
}
//Eventum #427 - Prevent test takers from retaking a finished test.
TestSubjectResult testSubjecResult=dataAccessor.getTestSubjectResult(login, resumekey);
if(testSubjecResult != null){
if(testSubjecResult.getRdscore() != null && testSubjecResult.getWrscore() != null && testSubjecResult.getLsscore() != null && testSubjecResult.getOlscore() != null){
if(testSubjecResult.getRdscore().getFinishtime() != null && testSubjecResult.getWrscore().getFinishtime() != null && testSubjecResult.getLsscore().getFinishtime() != null && testSubjecResult.getOlscore().getFinishtime() != null){
log_.debug(String.format("Already completed all the Skill Tests.", login.toString(), studentname));
session.setAttribute("logoutpage", true);
resetToken(request);
return mapping.findForward("continue-alldone");
}
}
}
// get a list of resumeable testtakers
List<Testtaker> resumeableTesttakers = new ArrayList<Testtaker>();
for(Testtaker testtaker : testtakers) {
if(testtaker.getPhase().equals(ConstantLibrary.PHASE_GOODBYE)) {
// testtaker is done with test. skip.
continue;
}
if(testtaker.getCurrentpanelid() == null) {
// testtaker is the profile testtaker
continue;
}
resumeableTesttakers.add(testtaker);
}
// sort them from least recent to latest
Collections.sort(resumeableTesttakers, new Comparator<Testtaker>() {
#Override
public int compare(Testtaker o1, Testtaker o2) {
// TODO Auto-generated method stub
//return 0;
return new CompareToBuilder()
.append(o1.getLasttouched(), o2.getLasttouched())
.toComparison();
}
});
if(resumeableTesttakers.size() == 0 && availiblePanels.size() > 0) {
// nobody is resumeable but there are panels left to take
// send them to the panel choice
// TODO: This is probably a misuse of Struts.
log_.info("No resumeable testtakers. Sending to panel select");
saveToken(request);
ActionForward myForward = (new ActionForward("/do/capstartpanel?capStartPanelAction=retest&lasttesttakerid="
+ testtakers.get(0).getTesttakerid(), true));
return myForward;// mapping.findForward(ConstantLibrary.FWD_CONTINUE + "-panel");
} else {
// grab the one most recently created and take their test
log_.info(String.format("Resuming with choice of %d testtakers", resumeableTesttakers.size()));
// we're forwarding to resume at this point, so we should do the some of the initialization
// that would have happened if we were still using getTesttaker() instead of getTesttakers() above.
session.setAttribute(ConstantLibrary.SESSION_LOGIN, login);
session.setAttribute(ConstantLibrary.SESSION_TESTTAKER, resumeableTesttakers.get(resumeableTesttakers.size()-1));
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_RESUME);
}
}
It's not a worth changing multiple returns to a single return statement per method. Actually, that will unnecessarily increase the burden of storing the result in a local variable and then making the return finally,
ActionForward result = null;
//scenario 1
result = ...
//scenario 2
result = ...
//scenario 3
result = ...
//finally
return result;
Hope this helps, but, it doesn't make much sense to me
As pointed out by others, having a single return statement does not necessarily make your code cleaner. However, in this case splitting up the method in smaller pieces probably makes the code more readable.
For example, this part:
// first check if token is set
if(!isTokenValid(request, true)) {
String errmsg="There was a problem with your login. Please close your browser then reopen it and try again. Make sure to click the Login button only ONCE.";
request.setAttribute("errormessage", errmsg);
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
// check the form for input errors
String errmsg = checkInput(form);
if (errmsg != null) {
request.setAttribute("errormessage", errmsg);
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
could be replaced by introducing two methods and using those to write:
If(tokenNotSet() || formHasErrors()){
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
By doing this on multiple places the structure of the algorithm becomes more clear, possibly giving you more insight in how this code could be refactored to adhere to your coding guidelines.
I would set a an action forward variable at the start of the method.
ActionForward actionForwardToReturn = null;
Then replace each of these two lines
return mapping.getInputForward();
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
with these two lines :
actionForwardToReturn = mapping.getInputForward()
actionForwardToReturn = mapping.findForward(ConstantLibrary.FWD_CONTINUE);
finally return the variable.
return actionForwardToReturn;
This shouldn't be too difficult :)
On a side note... (actually the orginal answer to the question) :
Multiple return statements can make it hard to debug code.
I personally would have just one action object that you return at the end of the method. The benefit of this, is that i can put a break point right on the return statement and look at exactly what that object is.
Any logging or other cross cutting concern I would want to add later, would only have to be done at one point. Otherwise I would have to add a log statement to every line where you are returning.
The complexity added to a method in an attempt to remove multiple return statements is many a times not worth it, especially in a method such as yours.There's nothing wrong with using them in this case.
Like user3580294 there's nothing wrong with multiple return statements. However you could combine the last two if statements since they are essentially returning the same thing.
Use #Octopus 's method if you absolutely have to have one return statement