I seem to create these two kind of methods occasionally:
// return null on errors, and append errors to 2nd param, otherwise return result
String fetchSomething(String parameter, List<String> errorMessagesOut);
// return empty list or null on no errors, otherwise list of errors
List<String> verifySomething(String parameter);
And then the code which calls these will join the error list with appropriate separator (such as simple comma, newline, HTML tags...), usually using Apache Commons Stringutils.join
method. And in normal case there's no error, and list will be empty.
So, I started wondering about these two questions:
Do you see a problem with returning error message strings as list? If so, what is better alternative? (Not exceptions, that would be thrown by code which calls these methods, when that is wanted.)
Is new LinkedList()
or new ArrayList(0)
or new ArrayList()
better for list which is expected to remain empty, and which should normally have only sequential iterator access when it is not empty?
EDIT: Example use case:
List<String> verifyParameters(JSONObject params) {
List<String> ret = new ArrayList<String>(0);
if (!verifyKey(params.get("key")))
ret.add("Invalid key: " + key);
if (!verifyAccess(params.get("user"), params.get("pass")))
ret.add("Authentication error");
return ret;
}
...
List<String> errors = verifyParameters(params);
if (!errors.isEmpty()) {
connection.sendErrorListMessage(errors);
logger.warn(StringUtils.join(errors, ", "));
controlPanel.show("Errors: \n- " + StringUtils.join(errors, "\n- ") + '\n');
throw new AbortException("invalid params); // or maybe return false/null;
}
// proceed with valid params
Usually handling of error list would not have all of those, it just tries to illustrate the point that error list is a list of messages meant for humans to see, independent of how it will be shown, and also not related to/useful for handling different errors differently.
Manipulating LinkedList takes less time compared to ArrayList because, in a doubly-linked list, there is no concept of shifting the memory bits. The list is traversed and the reference link is changed. This class implements a List interface. Therefore, this acts as a list. This class implements both the List interface and the Deque interface.
The isEmpty method of the LinkedList class returns true if the LinkedList object is empty. The isEmpty method returns a boolean value indicating whether there are any elements in the LinkedList (i.e. it is empty or not).
Collections.emptyList () returns a list ( java.util.Collections.EmptyList) that can't be modified. When creating a new list instance you can modify it depending on the implementation: 3. Object Creation Collection.emptyList () creates a new empty list instance only once, as shown in source code:
The core difference between java.util.Collections.emptyList () and a new list e.g. new ArrayList<> () is immutability. Collections.emptyList () returns a list ( java.util.Collections.EmptyList) that can't be modified.
I think it's fine to use a List for the Strings. I would be inclined to make a dedicated Result
class at least for fetchSomthing
and make it like this, especially if the errorMessagesOut
passed is never anything except a new empty List:
Result result = fetchSomething(String parameter);
if (result.hasErrors()) {
List<String> errors = result.getErrors();
} else {
String fetched = result.getValue();
}
I would then also put any of the methods that process the error Strings on this class also so you could do something like:
String errorMessage = result.getErrorString();
This encapsulates the error data and the formatting of it within the one Class and means that in the case of no errors you don't need to create any List internally in your Result instance.
My above points are mostly about the code design. There is no point in trying micro-optimization without profiling and having benchmarks to compare to the results of any changes.
What are these errors for? Are you going to do some business decision off of the errors returned by a method? Otherwise, if the errors are just for logging, a simple Logging solution would suggest that the errors are logged as soon as they occur. I'm talking about those logger.debug("Error message");
.
Anyway, could you give us an example of what is done to this errors after they are returned?
One thing I point, though: It tends to be confusing if you're using the same array / list / collection for both processing results and for errors. It would also be confusing if your methods returned error lists (or empty/null lists in case of no error) as it would appear that the errors are the very result of executing your method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With