how to return multiple Integer in java? - java

i have a method which will return an error code(int) and a result(int). If the error code is 0, the result is valid.
In c++, this may like:
int method(int& result);
Java calls by reference, so if we change a object in a method, the change is visible by the caller. But, int is not a class, so I could't make is like this in java:
int method(int result);
And Integer and Long are immutable in Java, so change is not visible by the caller if i do it like this:
Integer method(Integer result);
Wrap the result into a Wrapper Class works! But, that's no so simple!
I work with c++ for long and move to java recently, this bother me a lot!
could any one provide a solution?
=================================
well, in a conclusion, there are these flowing solutions:
pass an array as parameter
pass a wrapper as parameter
return a pair
return a wrapper containing error number and result
throw exception
pass a mutableint
1st and 2nd make my api ugly
3rd and 4th seems not so perfect
about 5th, this method is frequantly called so i've to take efficiency into consideration
6th seems match my require most
thanks!

Don't use return codes for errorcodes: use Exceptions; it is what they are for. Just return the actual result.

You can't return more than one integer for your method. What you can do is:
Create a new object with 2 integer fields and let your method return an instance of that object (basically a wrapper);
Make your method return an array of 2 integers (or take it as a parameter);
Make your method return a String variable of the form <int 1>,<int 2>. You can then use the split() to get the numbers from the string and parse them back to integers.
Make your method throw the exception and return the number.

You are correct that you would need to wrap the values. If the call to method will not be too frequent, consider throwing an exception to report failure and exit cleanly otherwise. That would be the most Java-esque approach. I use this pattern in my C++ code as well (I do not like output parameters and return values in the same method unless there are other pressures requiring it).
However, performance sometimes requires the more C-system-call-ish style you are using. In that case I recommend you construct a Result type and an Error type that you can set the value of.
Something else to consider is to have a Generic (read "templated") class named TwoTuple<TYPE1, TYPE2> that you can use to pass pairs of values around. I've found that in Java I do a lot of pair-passing, though that might be a derivative of my personal style. :)

I would suggest creating a custom Object to hold both pieces of data, e.g.
public class ResultData {
private int result;
private int errorCode;
public ResultData(int errorCode, int result) {
this.result = result;
this.errorCode = errorCode;
}
// Getters...
}
Then your method becomes:
public ResultData method() {
// Do stuff
return new ResultData(error, result);
}
Alternatively, as other answers have suggested, use Exceptions to signify if an error has occurred and that way if the method returns a result you can always be sure that it is valid. Catching the Exception signifies that an error occurred and you can handle it the way you would have handled the errorCode.

There are two ways to handle the scenario :-
1. Have a special values for error codes to distinguish them from result values ( if that is possible). For example, the indexOf() method in java's ArrayList returns -1 if the element is not present in the list, otherwise returns the positive index.
2. Use exceptions for erroneous conditions and always treat the return value as correct result. That is, if the method returns without any exception, assume exit code to be 0 and store the return value into result.
Creating a custom object to store the result and exit code might be an overkill.

There's a MutableInt component in the Apache Commons library. Since it's mutable, you can pass it by reference.

Not very nice, but:
int method(int[] result) {
result[0] = 1; // set result[0] as your out value
// etc.
}
Using an array to create an "artificial reference" towards a single int.

Returning an error code is not a good practice in Java. Instead use exceptions... And list for multiuple values...
List<Integer> method(Parameter... paramteters)
{
List<Integer> listOfValues = ...
//some calculations
if(errorCondition) throw new SomeException();
//more calculations, if needed
return listOfValues;
}

Return an object containing the two integers, eg. using commons-lang v3 Pair
Pair<Integer, Integer> method(){
return Pair.of(a,b)
}

Firstly, an int error code? Generally considered poor in Java. Exception is usual (but slow when executed). If it's actually common and/or performance is critical, then return something meaningful. Perhaps a nice new [2004] enum.
So in general, how to return multiple values. You could hack it and use AtomicInteger or similar. Please don't use an array!
Better would be to return a meaningful (probably immutable) object. Pair<,> is not a meaningful object. (There have been some suggestions for making this easier in a future version of the language.)
A more exotic way is to pass in a callback object. this is particularly useful if the result data differs depending upon possible result types. Have the method return void (or possibly the result of the callback) and add a parameter. Call a method depending upon the result type. Add as many arguments (within taste) and methods as useful. A typical caller would use an anonymous inner class, and not have to switch on error code. Of course, returning to the enclosing method again raises the problem of how to get the data out.

In your case, if you have a error, throw an appropriate exception. You have exceptions in C++ also.
Anything else is a valid result.
However to answer your question on how to return multiple values.
An approach I use in many places is to use a listener interface
interface ErrorOrResult {
void onError(int error);
void onResult(int result);
}
a.method(errorOrResultImpl); // can use an anonymous implementation here.
As you can see, different types of result can be called any number of times with a variety of arguments.
You could return a Object with two fields. This is the most object orientated way.
If it bothers you that an object is created each time, you can pass an object as an argument.
The simplest being an int[] which you reuse.
int[] results = { 0, 0 };
a.method(results);
An alterative is to return a long.
long result = a.method();
// split into two int values.
Or to make the method stateful.
int error = a.method();
int result = a.methodResult();
Or you can use the sign like Collections.binarySearch does
int errorOrResult = a.method();
if (errorOresult < 0)
int error = ~errorOrResult;
else
int result = errorOrResult;
Given there are so many alternatives, it may a while before multiple return values are allowed.

Related

Returning multiple primitive objects in java . Unrecommended?

I'm just beginning to learn OOP programming in java. I have already programmed a little in C++, and one of the things I miss the most in Java is the possibility to return multiple values. It's true that C++ functions only strictly return one variable, but we can use the by-reference parameters to return many more. Conversely, in Java we can't do such a thing, at least we can't for primitive types.
The solution I thought off was to create a class grouping the variables I wanted to return and return an instance of that class. For example, I needed to look for an object in a an array and I wanted to return a boolean(found or not) and an index. I know I could make this just setting the index to -1 if nothing was found, but I think it's more clear the other way.
The thing is that I was told by someone who knows much more about Java than I know that I shouldn't create classes for the purpose of returning multiple values ( even if they are related). He told classes should never be used as C++ structs, just to group elements. He also said methods shouldn't return non-primitive objects , they should receive the object from the outside and only modify it. Which of these things are true?
I shouldn't create classes for the purpose of returning multiple values
classes should never be used as C++ structs, just to group elements.
methods shouldn't return non-primitive objects, they should receive the object from the outside and only modify it
For any of the above statements this is definitely not the case. Data objects are useful, and in fact, it is good practice to separate pure data from classes containing heavy logic.
In Java the closest thing we have to a struct is a POJO (plain old java object), commonly known as data classes in other languages. These classes are simply a grouping of data. A rule of thumb for a POJO is that it should only contain primitives, simple types (string, boxed primitives, etc) simple containers (map, array, list, etc), or other POJO classes. Basically classes which can easily be serialized.
Its common to want to pair two, three, or n objects together. Sometimes the data is significant enough to warrant an entirely new class, and in others not. In these cases programmers often use Pair or Tuple classes. Here is a quick example of a two element generic tuple.
public class Tuple2<T,U>{
private final T first;
private final U second;
public Tuple2(T first, U second) {
this.first = first;
this.second = second;
}
public T getFirst() { return first; }
public U getSecond() { return second; }
}
A class which uses a tuple as part of a method signature may look like:
public interface Container<T> {
...
public Tuple2<Boolean, Integer> search(T key);
}
A downside to creating data classes like this is that, for quality of life, we have to implement things like toString, hashCode, equals getters, setters, constructors, etc. For each different sized tuple you have to make a new class (Tuple2, Tuple3, Tuple4, etc). Creating all of these methods introduce subtle bugs into our applications. For these reasons developers will often avoid creating data classes.
Libraries like Lombok can be very helpful for overcoming these challenges. Our definition of Tuple2, with all of the methods listed above, can be written as:
#Data
public class Tuple2<T,U>{
private final T first;
private final U second;
}
This also makes it extremely easy to create custom response classes. Using the custom classes can avoid autoboxing with generics, and increase readability greatly. eg:
#Data
public class SearchResult {
private final boolean found;
private final int index;
}
...
public interface Container<T> {
...
public SearchResult search(T key);
}
methods should receive the object from the outside and only modify it
This is bad advice. It's much nicer to design data around immutability. From Effective Java 2nd Edition, p75
Immutable objects are simple. An immutable object can be in exactly one state, the state in which it was created. If you make sure that all constructors establish class invariants, then it is guaranteed that these invariants will remain true for all time, with no further effort on your part or on the part of the programmer who uses the class. Mutable objects, on the other hand, can have arbitrarily complex state spaces. If the documentation does not provide a precise description of the state transitions performed by mutator methods, it can be difficult or impossible to use a mutable class reliably.
Immutable objects are inherently thread-safe; they require no synchronization. They cannot be corrupted by multiple threads accessing them concurrently. This is far and away the easiest approach to achieving thread safety. In fact, no thread can ever observe any effect of another thread on an immutable object. Therefore, immutable objects can be shared freely.
As to your specific example ("how to return both error status and result?")
I needed to look for an object in a an array and I wanted to return a boolean(found or not) and an index. I know I could make this just setting the index to -1 if nothing was found, but I think it's more clear the other way.
Returning special invalid result values such as -1 for "not found" is indeed very common, and I agree with you that it is not too pretty.
However, returning a tuple of (statusCode, resultValue) is not the only alternative.
The most idiomatic way to report exceptions in Java is to, you guessed it, use exceptions. So return a result or if no result can be produced throw an exception (NoSuchElementException in this case). If this is appropriate depends on the application: You don't want to throw exceptions for "correct" input, it should be reserved for irregular cases.
In functional languages, they often have built-in data structures for this (such as Try, Option or Either) which essentially also do statusCode + resultValue internally, but make sure that you actually check that status code before trying to access the result value. Java now has Optional as well. If I want to go this route, I'd pull in these wrapper types from a library and not make up my own ad-hoc "structs" (because that would only confuse people).
"methods shouldn't return non-primitive objects , they should receive the object from the outside and only modify it"
That may be very traditional OOP thinking, but even within OOP the use of immutable data absolutely has its value (the only sane way to do thread-safe programming in my book), so the guideline to modify stuff in-place is pretty terrible. If something is considered a "data object" (as opposed to "an entity") you should prefer to return modified copies instead of mutating the input.
For some static Information you can use the static final options. Variables, declared as static final, can be accessed from everywhere.
Otherwise it is usual and good practise to use the getter/ setter concept to receive and set parameters in your classes.
Strictly speaking, it is a language limitation that Java does not natively support tuples as return values (see related discussion here). This was done to keep the language cleaner. However, the same decision was made in most other languages. Of course, this was done keeping in mind that, in case of necessity, such a behaviour can be implemented by available means. So here are the options (all of them except the second one allow to combine arbitrary types of return components, not necessarily primitive):
Use classes (usually static, self-made or predefined) specifically designed to contain a group of related values being returned. This option is well covered in other answers.
Combine, if possible, two or more primitive values into one return value. Two ints can be combined into a single long, four bytes can be combined into a single int, boolean and unsigned int less than Integer.MAX_VALUE can be combined into a signed int (look, for example, at how Arrays.binarySearch(...) methods return their results), positive double and boolean can be combined into a single signed double, etc. On return, extract the components via comparisons (if boolean is among them) and bit operations (for shifted integer components).
2a. One particular case worth noting separately. It is common (and widely used) convention to return null to indicate that, in fact, the returned value is invalid. Strictly speaking, this convention substitutes two-field result - one implicit boolean field that you're using when checking
if (returnValue != null)
and the other non-primitive field (which can be just a wrapper of a primitive field) containing the result itself. You use it after the above checking:
ResultClass result = returnValue;
If you don't want to mess with data classes, you can always return an array of Objects:
public Object[] returnTuple() {
return new Object[]{1234, "Text", true};
}
and then typecast its components to desired types:
public void useTuple() {
Object[] t = returnTuple();
int x = (int)t[0];
String s = (String)t[1];
boolean b = (boolean)t[2];
System.out.println(x + ", " + s + ", " + b);
}
You can introduce field(s) into your class to hold auxiliary return component(s) and return only the main component explicitly (you decide which one is the main component):
public class LastResultAware {
public static boolean found;
public static int errorCode;
public static int findLetter(String src, char letter) {
int i = src.toLowerCase().indexOf(Character.toLowerCase(letter));
found = i >= 0;
return i;
}
public static int findUniqueLetter(String src, char letter) {
src = src.toLowerCase();
letter = Character.toLowerCase(letter);
int i = src.indexOf(letter);
if (i < 0)
errorCode = -1; // not found
else {
int j = src.indexOf(letter, i + 1);
if (j >= 0)
errorCode = -2; // ambiguous result
else
errorCode = 0; // success
}
return i;
}
public static void main(String[] args) {
int charIndex = findLetter("ABC", 'b');
if (found)
System.out.println("Letter is at position " + charIndex);
charIndex = findUniqueLetter("aBCbD", 'b');
if (errorCode == 0)
System.out.println("Letter is only at position " + charIndex);
}
}
Note that in some cases it is better to throw an exception indicating an error than to return an error code which the caller may just forget to check.
Depending on usage, this return-extending fields may be either static or instance. When static, they can even be used by multiple classes to serve a common purpose and avoid unnecessary field creation. For example, one public static int errorCode may be enough. Be warned, however, that this approach is not thread-safe.

Generic methods returning dynamic object types

Possibly a question which has been asked before, but as usual the second you mention the word generic you get a thousand answers explaining type erasure. I went through that phase long ago and know now a lot about generics and their use, but this situation is a slightly more subtle one.
I have a container representing a cell of data in an spreadsheet, which actually stores the data in two formats: as a string for display, but also in another format, dependent on the data (stored as object). The cell also holds a transformer which converts between the type, and also does validity checks for type (e.g. an IntegerTransformer checks if the string is a valid integer, and if it is returns an Integer to store and vice versa).
The cell itself is not typed as I want to be able to change the format (e.g. change the secondary format to float instead of integer, or to raw string) without having to rebuild the cell object with a new type. a previous attempt did use generic types but unable to change the type once defined the coding got very bulky with a lot of reflection.
The question is: how do I get the data out of my Cell in a typed way? I experimented and found that using a generic type could be done with a method even though no constraint was defined
public class Cell {
private String stringVal;
private Object valVal;
private Transformer<?> trans;
private Class<?> valClass;
public String getStringVal(){
return stringVal;
}
public boolean setStringVal(){
//this not only set the value, but checks it with the transformer that it meets constraints and updates valVal too
}
public <T> T getValVal(){
return (T) valVal;
//This works, but I don't understand why
}
}
The bit that puts me off is: that is ? it can't be casting anything, there is no input of type T which constrains it to match anything, actually it doesn't really say anything anywhere. Having a return type of Object does nothing but give casting complications everywhere.
In my test I set a Double value, it stored the Double (as an object), and when i did Double testdou = testCell.getValVal(); it instantly worked, without even an unchecked cast warning. however, when i did String teststr = testCell.getValVal() I got a ClassCastException. Unsurprising really.
There are two views I see on this:
One: using an undefined Cast to seems to be nothing more than a bodge way to put the cast inside the method rather than outside after it returns. It is very neat from a user point of view, but the user of the method has to worry about using the right calls: all this is doing is hiding complex warnings and checks until runtime, but seems to work.
The second view is: I don't like this code: it isn't clean, it isn't the sort of code quality I normaly pride myself in writing. Code should be correct, not just working. Errors should be caught and handled, and anticipated, interfaces should be foolproof even if the only expecter user is myself, and I always prefer a flexible generic and reusable technique to an awkward one off. The problem is: is there any normal way to do this? Is this a sneaky way to achieve the typeless, all accepting ArrayList which returns whatever you want without casting? or is there something I'm missing here. Something tells me I shouldn't trust this code!
perhaps more of a philosophical question than I intended but I guess that's what I'm asking.
edit: further testing.
I tried the following two interesting snippets:
public <T> T getTypedElem() {
T output = (T) this.typedElem;
System.out.println(output.getClass());
return output;
}
public <T> T getTypedElem() {
T output = null;
try {
output = (T) this.typedElem;
System.out.println(output.getClass());
} catch (ClassCastException e) {
System.out.println("class cast caught");
return null;
}
return output;
}
When assigning a double to typedElem and trying to put it into a String I get an exception NOT on the cast to , but on the return, and the second snippet does not protect. The output from the getClass is java.lang.Double, suggesting that is being dynamically inferred from typedElem, but that compiler level type checks are just forced out of the way.
As a note for the debate: there is also a function for getting the valClass, meaning it's possible to do an assignability check at runtime.
Edit2: result
After thinking about the options I've gone with two solutions: one the lightweight solution, but annotated the function as #depreciated, and second the solution where you pass it the class you want to try to cast it as. this way it's a choice depending on the situation.
You could try type tokens:
public <T> T getValue(Class<T> cls) {
if (valVal == null) return null;
else {
if (cls.isInstance(valVal)) return cls.cast(valVal);
return null;
}
}
Note, that this does not do any conversion (i.e., you cannot use this method to extract a Double, if valVal is an instance of Float or Integer).
You should get, btw., a compiler warning about your definition of getValVal. This is, because the cast cannot be checked at run-time (Java generics work by "erasure", which essentially means, that the generic type parameters are forgotten after compilation), so the generated code is more like:
public Object getValVal() {
return valVal;
}
As you are discovering, there is a limit to what can be expressed using Java's type system, even with generics. Sometimes there are relationships between the types of certain values which you would like to assert using type declarations, but you can't (or perhaps you can, at the cost of excess complexity and long, verbose code). I think the sample code in this post (question and answers) is a good illustration of that.
In this case, the Java compiler could do more type checking if you stored the object/string representation inside the "transformer". (Perhaps you'll have to rethink what it is: maybe it's not just a "transformer".) Put a generic bound on your base Transformer class, and make that same bound the type of the "object".
As far as getting the value out of the cell, there's no way that compiler type checking will help you there, since the value can be of different types (and you don't know at compile time what type of object will be stored in a given cell).
I believe you could also do something similar to:
public <T> void setObject(Transformer<T> transformer, T object) {}
If the only way to set the transformer and object is through that method, compiler type checking on the arguments will prevent an incompatible transformer/object pair from going into a cell.
If I understand what you're doing, the type of Transformer which you use is determined solely by the type of object which the cell is holding, is that right? If so, rather than setting the transformer/object together, I would provide a setter for the object only, and do a hash lookup to find the appropriate transformer (using the object type as key). The hash lookup could be done every time the value is set, or when it is converted to a String. Either way would work.
This would naturally make it impossible for the wrong type of Transformer to be passed in.
I think you are a static-typed guy, but lemme try: have you thought about using a dynamic language like groovy for that part?
From your description it seems to me like types are more getting in the way than helping anything.
In groovy you can let the Cell.valVal be dynamic typed and get an easy transformation around:
class Cell {
String val
def valVal
}
def cell = new Cell(val:"10.0")
cell.valVal = cell.val as BigDecimal
BigDecimal valVal = cell.valVal
assert valVal.class == BigDecimal
assert valVal == 10.0
cell.val = "20"
cell.valVal = cell.val as Integer
Integer valVal2 = cell.valVal
assert valVal2.class == Integer
assert valVal2 == 20
Where as it's everything needed for the most common transformations. You can add yours too.
If needing to transform other blocks of code, note that java's syntax is valid groovy syntax, except for the do { ... } while() block

Passing a parameter versus returning it from function

As it might be clear from the title which approach should we prefer?
Intention is to pass a few method parameters and get something as output. We can pass another parameter and method will update it and method need not to return anything now, method will just update output variable and it will be reflected to the caller.
I am just trying to frame the question through this example.
List<String> result = new ArrayList<String>();
for (int i = 0; i < SOME_NUMBER_N; i++) {
fun(SOME_COLLECTION.get(i), result);
}
// in some other class
public void fun(String s, List<String> result) {
// populates result
}
versus
List<String> result = new ArrayList<String>();
for (int i = 0; i < SOME_NUMBER_N; i++) {
List<String> subResult = fun(SOME_COLLECTION.get(i));
// merges subResult into result
mergeLists(result, subResult);
}
// in some other class
public List<String> fun(String s) {
List<String> res = new ArrayList<String>();
// some processing to populate res
return res;
}
I understand that one passes the reference and another doesn't.
Which one should we prefer (in different situations) and why?
Update: Consider it only for mutable objects.
Returning a value from the function is generally a cleaner way of writing code. Passing a value and modifying it is more C/C++ style due to the nature of creating and destroying pointers.
Developers generally don't expect that their values will be modified by passing it through a function, unless the function explicitly states it modifies the value (and we often skim documentation anyway).
There are exceptions though.
Consider the example of Collections.sort, which does actually do an in place sort of a list. Imagine a list of 1 million items and you are sorting that. Maybe you don't want to create a second list that has another 1 million entries (even though these entries are pointing back to the original).
It is also good practice to favor having immutable objects. Immutable objects cause far fewer problems in most aspects of development (such as threading). So by returning a new object, you are not forcing the parameter to be mutable.
The important part is to be clear about your intentions in the methods. My recommendation is to avoid modifying the parameter when possible since it not the most typical behavior in Java.
You should return it. The second example you provided is the way to go.
First of all, its more clear. When other people read your code, there's no gotcha that they might not notice that the parameter is being modified as output. You can try to name the variables, but when it comes to code readability, its preferable.
The BIG reason why you should return it rather than pass it, is with immutable objects.
Your example, the List, is mutable, so it works okay.
But if you were to try to use a String that way, it would not work.
As strings are immutable, if you pass a string in as a parameter, and then the function were to say:
public void fun(String result){
result = "new string";
}
The value of result that you passed in would not be altered. Instead, the local scope variable 'result' now points to a new string inside of fun, but the result in your calling method still points to the original string.
If you called:
String test = "test";
fun(test);
System.out.println(test);
It will print: "test", not "new string"!
So definitely, it is superior to return. :)
This is more about best practices and your own method to program. I would say if you know this is going to be a one value return type function like:
function IsThisNumberAPrimeNumber{ }
Then you know that this is only going to ever return a boolean. I usually use functions as helper programs and not as large sub procedures. I also apply naming conventions that help dictate what I expect the sub\function will return.
Examples:
GetUserDetailsRecords
GetUsersEmailAddress
IsEmailRegistered
If you look at those 3 names, you can tell the first is going to give you some list or class of multiple user detail records, the second will give you a string value of a email and the third will likely give you a boolean value. If you change the name, you change the meaning, so I would say consider this in addition.
The reason I don't think we understand is that those are two totally different types of actions. Passing a variable to a function is a means of giving a function data. Returning it from the function is a way of passing data out of a function.
If you mean the difference between these two actions:
public void doStuff(int change) {
change = change * 2;
}
and
public void doStuff() {
int change = changeStorage.acquireChange();
change = change * 2;
}
Then the second is generally cleaner, however there are several reasons (security, function visibilty, etc) that can prevent you from passing data this way.
It's also preferable because it makes reusing code easier, as well as making it more modular.
according to guys recommendation and java code convention and also syntax limitation this is a bad idea and makes code harder to understand
BUT you can do it by implementing a reference holder class
public class ReferenceHolder<T>{
public T value;
}
and pass an object of ReferenceHolder into method parameter to be filled or modified by method.
on the other side that method must assign its return into Reference value instead of returning it.
here is the code for getting result of an average method by a ReferenceHolder instead of function return.
public class ReferenceHolderTest {
public static void main(String[] args) {
ReferenceHolder<Double> out = new ReferenceHolder<>();
average(new int[]{1,2,3,4,5,6,7,8},out);
System.out.println(out.value);
}
public static void average(int[] x, ReferenceHolder<Double> out ) {
int sum=0;
for (int a : x) {
sum+=a;
}
out.value=sum/(double)x.length;
}
}
Returning it will keep your code cleaner and cause less coupling between methods/classes.
It is generally preferable to return it.
Specially from a unit testing standpoint. If you are unit testing it
is easier to assert a returned value from a method than verifying if
your object was modified or interacted correctly. (Using
ArgumentCaptor or ArgumentMatcher to assert interactions isn't as
straight forward as a simple return assertion).
Increased code readability. If I see a method that takes 5 object parameters I
might have no immediate way of knowing you plan on modifying one of
those references for future use downstream. Instead if you are returning an
object, I can easily see you ultimately care about the result of that
method's computation.

how to return two values(1.Collection, 2.Single Boolean value) from a method in java with less expense?

I have one Main class and VOCollection Class.
in main class there is a method called getStatus(), from this method only i am getting some status(true,false), if the status is true, i need to return a collection.
at present i have two ideas, but both are expensive.
return map, it's expensive because setting Boolean for collection make confusion in code, and only one Boolean value is enough (but we are returning multiple).
creating an instance variable in VOCollection class, and having getter & setter to get & set the Boolean value. this is also expensive. (creating a variable in another class).
give me less expensive solution.
There are a number of ways to do this:
Return null to indicate that there is nothing present like java.util.Map.get()
Create a custom class to return both parameters. (See other answer)
Use a 1 element array for one of the return values.
boolean method(List[] result) {
result[0] = answer;
return flag;
}
Use a library like Google Guava that has a Pair/Tuple class:
Pair method() {
return new Pair(flag, answer);
}
Change your code so that it isn't necesssary, this is usually the right answer. See the exception comment or change the way things are passed around.
The desire to return either an object or a boolean is smelly. You see this kind of "flag" very often in code of starters who don't fully understand how to handle exceptional or "nothing" outcomes.
If the boolean represents an exception, just let it go or rethrow it in another exception. E.g. IllegalArgumentException, IllegalStateException, UnsupportedOperationException, etc depending on the functional requirement. You can put the calling code in a try-catch and handle it accordingly.
Or if the boolean represents a state of "nothing", just return null or an empty collection. You can handle it by testing the return value after calling the method.
You can introduce an class like this
class StatusResult
{
public final bool status;
public final VOCollection result;
...
}
and change the signature of getStatus() to
StatusResult getStatus()
I have come across the same situation in my past.
Both the solutions which you have mentioned are feasible as you said they may be expensive.
In fact, Java doesnot support the multiple return values from a method.
Solution Which I implemented was
I will try to parse/create/encode the string in such a way, after decoding i should be able to know what i need to do.
In your case, I would have choosen the following path
Create a string like returnValue, let that string start with either 0 or 1, if its 1 its true, else false.
and append the second return value to that.
For example you are trying to return like "returnValue1" and "true"
for true let us keep it 1 and for false lets keep it 2
when you do this, your return value will become "1returnValue1"
Simply return the collection when 'status is true'. Otherwise return null.
But:
Getting a collection with calling a method named "getStatus()" is not what I would expect.
"getStatus()" sounds getting some constant value indicating internal state. (like enum constant, int status code whatever)
In your scenario I would recommend having one method returning a boolean indicating that "i have something or not" and another method returning the collection - that what you have or null when not.
The boolean-method can then be easy implemented by calling the collection-method checking != null.
public boolean isXyz() {
return getXyz() != null;
}
public Collection getXyz() {
return yourCollection; //maybe null
}
The simplest approach may be to always return a VOCollection. For the situation where there is no data you could return a collection with no data i.e. isEmpty() is true, or a collection which has a flag (but I prefer the first option).
To avoid creating an object each time, create a single instance of an immutable VOCollection with no entries. This is what you can return when you have no data.

Should Java method arguments be used to return multiple values?

Since arguments sent to a method in Java point to the original data structures in the caller method, did its designers intend for them to used for returning multiple values, as is the norm in other languages like C ?
Or is this a hazardous misuse of Java's general property that variables are pointers ?
A long time ago I had a conversation with Ken Arnold (one time member of the Java team), this would have been at the first Java One conference probably, so 1996. He said that they were thinking of adding multiple return values so you could write something like:
x, y = foo();
The recommended way of doing it back then, and now, is to make a class that has multiple data members and return that instead.
Based on that, and other comments made by people who worked on Java, I would say the intent is/was that you return an instance of a class rather than modify the arguments that were passed in.
This is common practice (as is the desire by C programmers to modify the arguments... eventually they see the Java way of doing it usually. Just think of it as returning a struct. :-)
(Edit based on the following comment)
I am reading a file and generating two
arrays, of type String and int from
it, picking one element for both from
each line. I want to return both of
them to any function which calls it
which a file to split this way.
I think, if I am understanding you correctly, tht I would probably do soemthing like this:
// could go with the Pair idea from another post, but I personally don't like that way
class Line
{
// would use appropriate names
private final int intVal;
private final String stringVal;
public Line(final int iVal, final String sVal)
{
intVal = iVal;
stringVal = sVal;
}
public int getIntVal()
{
return (intVal);
}
public String getStringVal()
{
return (stringVal);
}
// equals/hashCode/etc... as appropriate
}
and then have your method like this:
public void foo(final File file, final List<Line> lines)
{
// add to the List.
}
and then call it like this:
{
final List<Line> lines;
lines = new ArrayList<Line>();
foo(file, lines);
}
In my opinion, if we're talking about a public method, you should create a separate class representing a return value. When you have a separate class:
it serves as an abstraction (i.e. a Point class instead of array of two longs)
each field has a name
can be made immutable
makes evolution of API much easier (i.e. what about returning 3 instead of 2 values, changing type of some field etc.)
I would always opt for returning a new instance, instead of actually modifying a value passed in. It seems much clearer to me and favors immutability.
On the other hand, if it is an internal method, I guess any of the following might be used:
an array (new Object[] { "str", longValue })
a list (Arrays.asList(...) returns immutable list)
pair/tuple class, such as this
static inner class, with public fields
Still, I would prefer the last option, equipped with a suitable constructor. That is especially true if you find yourself returning the same tuple from more than one place.
I do wish there was a Pair<E,F> class in JDK, mostly for this reason. There is Map<K,V>.Entry, but creating an instance was always a big pain.
Now I use com.google.common.collect.Maps.immutableEntry when I need a Pair
See this RFE launched back in 1999:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4222792
I don't think the intention was to ever allow it in the Java language, if you need to return multiple values you need to encapsulate them in an object.
Using languages like Scala however you can return tuples, see:
http://www.artima.com/scalazine/articles/steps.html
You can also use Generics in Java to return a pair of objects, but that's about it AFAIK.
EDIT: Tuples
Just to add some more on this. I've previously implemented a Pair in projects because of the lack within the JDK. Link to my implementation is here:
http://pbin.oogly.co.uk/listings/viewlistingdetail/5003504425055b47d857490ff73ab9
Note, there isn't a hashcode or equals on this, which should probably be added.
I also came across this whilst doing some research into this questions which provides tuple functionality:
http://javatuple.com/
It allows you to create Pair including other types of tuples.
You cannot truly return multiple values, but you can pass objects into a method and have the method mutate those values. That is perfectly legal. Note that you cannot pass an object in and have the object itself become a different object. That is:
private void myFunc(Object a) {
a = new Object();
}
will result in temporarily and locally changing the value of a, but this will not change the value of the caller, for example, from:
Object test = new Object();
myFunc(test);
After myFunc returns, you will have the old Object and not the new one.
Legal (and often discouraged) is something like this:
private void changeDate(final Date date) {
date.setTime(1234567890L);
}
I picked Date for a reason. This is a class that people widely agree should never have been mutable. The the method above will change the internal value of any Date object that you pass to it. This kind of code is legal when it is very clear that the method will mutate or configure or modify what is being passed in.
NOTE: Generally, it's said that a method should do one these things:
Return void and mutate its incoming objects (like Collections.sort()), or
Return some computation and don't mutate incoming objects at all (like Collections.min()), or
Return a "view" of the incoming object but do not modify the incoming object (like Collections.checkedList() or Collections.singleton())
Mutate one incoming object and return it (Collections doesn't have an example, but StringBuilder.append() is a good example).
Methods that mutate incoming objects and return a separate return value are often doing too many things.
There are certainly methods that modify an object passed in as a parameter (see java.io.Reader.read(byte[] buffer) as an example, but I have not seen parameters used as an alternative for a return value, especially with multiple parameters. It may technically work, but it is nonstandard.
It's not generally considered terribly good practice, but there are very occasional cases in the JDK where this is done. Look at the 'biasRet' parameter of View.getNextVisualPositionFrom() and related methods, for example: it's actually a one-dimensional array that gets filled with an "extra return value".
So why do this? Well, just to save you having to create an extra class definition for the "occasional extra return value". It's messy, inelegant, bad design, non-object-oriented, blah blah. And we've all done it from time to time...
Generally what Eddie said, but I'd add one more:
Mutate one of the incoming objects, and return a status code. This should generally only be used for arguments that are explicitly buffers, like Reader.read(char[] cbuf).
I had a Result object that cascades through a series of validating void methods as a method parameter. Each of these validating void methods would mutate the result parameter object to add the result of the validation.
But this is impossible to test because now I cannot stub the void method to return a stub value for the validation in the Result object.
So, from a testing perspective it appears that one should favor returning a object instead of mutating a method parameter.

Categories