Why there is no BooleanConsumer in Java 8? - java

I'm afraid that this is somewhat a silly question.
Is there anybody can tell me why there is no BooleanConsumer opposite to BooleanSupplier?
Is there any reason other than "because simply there isn't"?
Should I create my own one? Or am I missing something else?
public interface BooleanConsumer {
void accept(boolean value);
default BooleanConsumer andThen(final BooleanConsumer after) {
return v -> {
accept(v);
after.accept(v);
}
}
}
Update
Where to use? I'm writing a library that uses much of consumers and suppliers. I successfully wrote a line with LongConsumer and I encountered a situation that expecting a consumer accepting a boolean value which is from a method result. Say Files.deleteIfExist?

IntConsumer and LongConsumer are needed to avoid the overhead autoboxing every value. It is much more efficent to be working on raw primitives.
However, for Boolean and Byte every possible object is cached so there is little reason to avoid using Consumer<Boolean> or Consumer<Byte>

As other answers indicate there is no great reason to avoid Consumer<Boolean>, but then there's no great reason to avoid Supplier<Boolean> either, so a different explanation is required for this.
A similar question is why can't you switch on a boolean value. The answer is that there's no need because you could always use if or if else.
A BooleanConsumer would really be nothing more than an if else construct because the accept() method for a BooleanConsumer could always be written in this form:
if (v) {
// Do something
} else {
// Do something else
}
If you needed to pass such code around as data, you could just pass a pair of Runnables representing "do something" and "do something else". In many cases, you would only need one of the Runnables because one of the two blocks above would be empty.
In the same way, there is no need for a BooleanPredicate because it would be nothing more than a pair of BooleanSuppliers and there is no need for a a BooleanFunction<R> because it would be nothing more than a pair of Supplier<R>s.
In contrast to this, it is not possible to break a BooleanSupplier into two simpler objects.

You can write your own BooleanConsumer, but in order to make it really useful, you would need to write your own BooleanStream, too. There is an IntStream, LongStream, and DoubleStream, but no "BooleanStream" (or "ShortStream", "FloatStream" etc). It seems that these primitives were judged not to be important enough.
You can always use Boolean objects instead of boolean primitives, and a Boolean Consumer to consume the values. Example code:
public class Main {
public static void main(String[] args) {
Consumer<Boolean> myConsumer = b -> System.out.println("b = " + b);
Stream.of("aa", "bb", "cc")
.map(Main::myBooleanFunction)
.forEach(myConsumer);
}
static boolean myBooleanFunction(String s) {
return s.startsWith("b");
}
}
myBooleanFunction returns a boolean, but using it in a map creates a stream of Booleans (because we are in the generic, non-primitive Stream. Again, we have mapToInt, mapToLong, mapToDouble to create an IntStream etc, but no mapToBoolean).
If you don't need stream support, you can still write and use a "BooleanConsumer" in order to provide a type for some behavior, put I would prefer to see a functional interface with a more specific and descriptive name.

Related

List of lambda suppliers, and equality [duplicate]

Say I have a List of object which were defined using lambda expressions (closures). Is there a way to inspect them so they can be compared?
The code I am most interested in is
List<Strategy> strategies = getStrategies();
Strategy a = (Strategy) this::a;
if (strategies.contains(a)) { // ...
The full code is
import java.util.Arrays;
import java.util.List;
public class ClosureEqualsMain {
interface Strategy {
void invoke(/*args*/);
default boolean equals(Object o) { // doesn't compile
return Closures.equals(this, o);
}
}
public void a() { }
public void b() { }
public void c() { }
public List<Strategy> getStrategies() {
return Arrays.asList(this::a, this::b, this::c);
}
private void testStrategies() {
List<Strategy> strategies = getStrategies();
System.out.println(strategies);
Strategy a = (Strategy) this::a;
// prints false
System.out.println("strategies.contains(this::a) is " + strategies.contains(a));
}
public static void main(String... ignored) {
new ClosureEqualsMain().testStrategies();
}
enum Closures {;
public static <Closure> boolean equals(Closure c1, Closure c2) {
// This doesn't compare the contents
// like others immutables e.g. String
return c1.equals(c2);
}
public static <Closure> int hashCode(Closure c) {
return // a hashCode which can detect duplicates for a Set<Strategy>
}
public static <Closure> String asString(Closure c) {
return // something better than Object.toString();
}
}
public String toString() {
return "my-ClosureEqualsMain";
}
}
It would appear the only solution is to define each lambda as a field and only use those fields. If you want to print out the method called, you are better off using Method. Is there a better way with lambda expressions?
Also, is it possible to print a lambda and get something human readable? If you print this::a instead of
ClosureEqualsMain$$Lambda$1/821270929#3f99bd52
get something like
ClosureEqualsMain.a()
or even use this.toString and the method.
my-ClosureEqualsMain.a();
This question could be interpreted relative to the specification or the implementation. Obviously, implementations could change, but you might be willing to rewrite your code when that happens, so I'll answer at both.
It also depends on what you want to do. Are you looking to optimize, or are you looking for ironclad guarantees that two instances are (or are not) the same function? (If the latter, you're going to find yourself at odds with computational physics, in that even problems as simple as asking whether two functions compute the same thing are undecidable.)
From a specification perspective, the language spec promises only that the result of evaluating (not invoking) a lambda expression is an instance of a class implementing the target functional interface. It makes no promises about the identity, or degree of aliasing, of the result. This is by design, to give implementations maximal flexibility to offer better performance (this is how lambdas can be faster than inner classes; we're not tied to the "must create unique instance" constraint that inner classes are.)
So basically, the spec doesn't give you much, except obviously that two lambdas that are reference-equal (==) are going to compute the same function.
From an implementation perspective, you can conclude a little more. There is (currently, may change) a 1:1 relationship between the synthetic classes that implement lambdas, and the capture sites in the program. So two separate bits of code that capture "x -> x + 1" may well be mapped to different classes. But if you evaluate the same lambda at the same capture site, and that lambda is non-capturing, you get the same instance, which can be compared with reference equality.
If your lambdas are serializable, they'll give up their state more easily, in exchange for sacrificing some performance and security (no free lunch.)
One area where it might be practical to tweak the definition of equality is with method references because this would enable them to be used as listeners and be properly unregistered. This is under consideration.
I think what you're trying to get to is: if two lambdas are converted to the same functional interface, are represented by the same behavior function, and have identical captured args, they're the same
Unfortunately, this is both hard to do (for non-serializable lambdas, you can't get at all the components of that) and not enough (because two separately compiled files could convert the same lambda to the same functional interface type, and you wouldn't be able to tell.)
The EG discussed whether to expose enough information to be able to make these judgments, as well as discussing whether lambdas should implement more selective equals/hashCode or more descriptive toString. The conclusion was that we were not willing to pay anything in performance cost to make this information available to the caller (bad tradeoff, punishing 99.99% of users for something that benefits .01%).
A definitive conclusion on toString was not reached but left open to be revisited in the future. However, there were some good arguments made on both sides on this issue; this is not a slam-dunk.
To compare labmdas I usually let the interface extend Serializable and then compare the serialized bytes. Not very nice but works for the most cases.
I don't see a possibility, to get those informations from the closure itself.
The closures doesn't provide state.
But you can use Java-Reflection, if you want to inspect and compare the methods.
Of course that is not a very beautiful solution, because of the performance and the exceptions, which are to catch. But this way you get those meta-informations.

Check whether method is overwritten in Java

I'd like to implement a method that compares two Objects of my interface Task. Since there will only be a strict partial ordering on Task, partialCompareTo should return null if and only if the two objects are incomparable.
If you are confused by the concept of a strict partial ordering, check this out:
https://en.wikipedia.org/wiki/Partially_ordered_set
Motivation: Some tasks will have the constraint that they have to be done before or after another task. This is then used to topological sort the tasks, i.e. arrange them in a way that all constraints are met.
It should have the following property, for any instances of Task a and b:
if a.partialCompareTo(b) != null then sgn(a.partialCompareTo(b)) = -sgn(b.partialCompareTo(a))
if a.partialCompareTo(b) = null then b.partialCompareTo(a) = null
Note: I can't use the interface Comparable of the standard library since there will be no total ordering on Task: compareTo in Comparable returns int, so there is no way for an adequate result if two objects are incomparable. In particular there will be implementations of Task, where instances of that implementations are never comparable to each other (but might be comparable to instances of other subclasses of Task, which override partialCompareTo).
The idea is to use the partialCompareTo method of the argument if it overrides the method specified in the class Task.
The following approach is actually more of a joke than an actual attempt, since every time two not comparable objects are compared we get an StackOverflowError (which is caught, but anyway this is not feasible):
public class Task implements TopologicalComparable<Task> {
/*
* other code
*/
#Override
public Integer partialCompareTo(Task other) {
Integer result;
try {
result = - other.partialCompareTo(this);
} catch (StackOverflowError | NullPointerException e) {
return null;
}
return null;
}
}
The following implementation is clearly better, but it has the downside, that one always has to override the helper method overridesDefaultPartialCompareTo:
public class Task implements TopologicalComparable<Task> {
/*
* other code
*/
#Override
public Integer partialCompareTo(Task other) {
if (other.overridesDefaultPCompareTo()) {
Integer revComp = other.overridesDefaultPartialCompareTo(this);
if (revComp != null) {
return - revComp;
}
}
return null;
}
public default boolean overridesDefaultPartialCompareTo() {
return false;
}
}
Is there a way to ask, whether the method is overwritten in code?
Or is there an alternative approach to solve my problem?
when you compare things you should using something with a comparable interface as recommended by duffymo. To go into detail, you should be keeping your items in an ArrayList then overwriting the compare method. I am not sure why you have pCompare, but I am going to assume you do not understand inheritance and polymorphism. Instead of changing the name of your compare you should be using extends, here are documents about Inheritance please read them. It looks like your syntax is good, but your understanding of how java code is written is not good. So how should you do this?
Lets start with the first thing I think is wrong (feel free to correct me guys if this is incorrect) you are not using an interface correctly. An interface is good for declaring global variables, helping you implement design patterns, and ect. Most people say it is a contract of behavior. In plain English use an interface to help you get past Multiple Inheritance. I have no idea why you are using one and what you plan to do with it, but I have never added a method to an interface that is implemented.
The next thing is you renaming your pCompareTo I have never done that and I have helped make some pretty large programs. I really don't think it is good programming. It should be in a class. The class that uses it is fine, though not always, and I am having a hard time thinking of how it can be explained so you might have to do some research.
When you get rid of the interface, put compareTo() in the correct place (do not change it to pCompareTo() that is bad programming) you override it like you did, and specify what goes into it. Pay attention this is important Usually when you override a compare to you have the compareTo Method you have it return -1 if the object coming in is smaller than what it is being compared to, 1 if it is larger or 0 if it is the same size. In the case where you just want to check if it is equal then you can simply check if they are equal like for string you do
string1.equals(string2)
and it will return 1 if true or 0 if false.
#Override
public default Integer pCompareTo(Task other) {
Integer result;
try {
result = - other.pCompareTo(this);
} catch (StackOverflowError | NullPointerException e) {
return null;
}
return null;
}
Ok this is horribly wrong man, just horribly wrong. Your method is pCompareTo() right? You are calling it inside itself (that is called recursion and I would not recommend you using that right now). I do not know what you are comparing (also a you don't need a try catch here but can if you want to, a try catch is like a trap you set in your code that goes off if that particular area did not work correctly), but if they were integers you would do something like
#Override
public int compareTo(Integer other){
if (this < other) {
return 1;
}
if (this > other) {
return -1;
}
return 0;
Please see override explanation. It is just to much for me to explain how it works to you in this already long post. Good luck, and my advice syntax in programming is not very important. Knowing how to program properly is much more important.
The revision is slightly better, and makes more sense. Thank you for that. Now to start off you need to understand that you are comparing objects. If you would like to write a compareTo() method you need to think about 'what am I comparing'. In order for you to write your method you need to explain to us what you are comparing, in your mind you might be comparing elements in a set. But in the programming world you are comparing ints, strings, or w/e you make them out of. So I ask you, what are you comparing? You should make a class of w/e you are comparing, say
class POsetElement{...
//make some sort of set element object
}
In this class you would want to implement comparable like so,
class POsetElement implements comparable{...
//make some sort of set element object...
//then make w/e other methods you need...
//now use compareTo() override
#override
compareTo(){
//make your custom method
}
}
Notice how I put the compareTo() method INSIDE the POsetElement class. Java is OOP. That means object oriented programming. You need to custom build objects. You need to make your own world,create your own objects. There is not way that I can explain all of this to you. Please put in some effort and learn more java programming. Also you need to understand I would say that these are some very basic things and once again I will reiterate that you need to read a bit on java basics. Good luck.

Is there a way to compare lambdas?

Say I have a List of object which were defined using lambda expressions (closures). Is there a way to inspect them so they can be compared?
The code I am most interested in is
List<Strategy> strategies = getStrategies();
Strategy a = (Strategy) this::a;
if (strategies.contains(a)) { // ...
The full code is
import java.util.Arrays;
import java.util.List;
public class ClosureEqualsMain {
interface Strategy {
void invoke(/*args*/);
default boolean equals(Object o) { // doesn't compile
return Closures.equals(this, o);
}
}
public void a() { }
public void b() { }
public void c() { }
public List<Strategy> getStrategies() {
return Arrays.asList(this::a, this::b, this::c);
}
private void testStrategies() {
List<Strategy> strategies = getStrategies();
System.out.println(strategies);
Strategy a = (Strategy) this::a;
// prints false
System.out.println("strategies.contains(this::a) is " + strategies.contains(a));
}
public static void main(String... ignored) {
new ClosureEqualsMain().testStrategies();
}
enum Closures {;
public static <Closure> boolean equals(Closure c1, Closure c2) {
// This doesn't compare the contents
// like others immutables e.g. String
return c1.equals(c2);
}
public static <Closure> int hashCode(Closure c) {
return // a hashCode which can detect duplicates for a Set<Strategy>
}
public static <Closure> String asString(Closure c) {
return // something better than Object.toString();
}
}
public String toString() {
return "my-ClosureEqualsMain";
}
}
It would appear the only solution is to define each lambda as a field and only use those fields. If you want to print out the method called, you are better off using Method. Is there a better way with lambda expressions?
Also, is it possible to print a lambda and get something human readable? If you print this::a instead of
ClosureEqualsMain$$Lambda$1/821270929#3f99bd52
get something like
ClosureEqualsMain.a()
or even use this.toString and the method.
my-ClosureEqualsMain.a();
This question could be interpreted relative to the specification or the implementation. Obviously, implementations could change, but you might be willing to rewrite your code when that happens, so I'll answer at both.
It also depends on what you want to do. Are you looking to optimize, or are you looking for ironclad guarantees that two instances are (or are not) the same function? (If the latter, you're going to find yourself at odds with computational physics, in that even problems as simple as asking whether two functions compute the same thing are undecidable.)
From a specification perspective, the language spec promises only that the result of evaluating (not invoking) a lambda expression is an instance of a class implementing the target functional interface. It makes no promises about the identity, or degree of aliasing, of the result. This is by design, to give implementations maximal flexibility to offer better performance (this is how lambdas can be faster than inner classes; we're not tied to the "must create unique instance" constraint that inner classes are.)
So basically, the spec doesn't give you much, except obviously that two lambdas that are reference-equal (==) are going to compute the same function.
From an implementation perspective, you can conclude a little more. There is (currently, may change) a 1:1 relationship between the synthetic classes that implement lambdas, and the capture sites in the program. So two separate bits of code that capture "x -> x + 1" may well be mapped to different classes. But if you evaluate the same lambda at the same capture site, and that lambda is non-capturing, you get the same instance, which can be compared with reference equality.
If your lambdas are serializable, they'll give up their state more easily, in exchange for sacrificing some performance and security (no free lunch.)
One area where it might be practical to tweak the definition of equality is with method references because this would enable them to be used as listeners and be properly unregistered. This is under consideration.
I think what you're trying to get to is: if two lambdas are converted to the same functional interface, are represented by the same behavior function, and have identical captured args, they're the same
Unfortunately, this is both hard to do (for non-serializable lambdas, you can't get at all the components of that) and not enough (because two separately compiled files could convert the same lambda to the same functional interface type, and you wouldn't be able to tell.)
The EG discussed whether to expose enough information to be able to make these judgments, as well as discussing whether lambdas should implement more selective equals/hashCode or more descriptive toString. The conclusion was that we were not willing to pay anything in performance cost to make this information available to the caller (bad tradeoff, punishing 99.99% of users for something that benefits .01%).
A definitive conclusion on toString was not reached but left open to be revisited in the future. However, there were some good arguments made on both sides on this issue; this is not a slam-dunk.
To compare labmdas I usually let the interface extend Serializable and then compare the serialized bytes. Not very nice but works for the most cases.
I don't see a possibility, to get those informations from the closure itself.
The closures doesn't provide state.
But you can use Java-Reflection, if you want to inspect and compare the methods.
Of course that is not a very beautiful solution, because of the performance and the exceptions, which are to catch. But this way you get those meta-informations.

how to return multiple Integer in 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.

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