When implement Predicate instead of boolean - java

I was reading a not related thread , when I read a comment: Any time I find myself needing a multi-line lambda, I move the lines to a private method and pass the method reference instead of the lambda.
I was asking: which is the correct way to implement this behaviour? With a boolean method as posted in comment, or with predicate?
Example:
let's say I wanna check if a Table is usable, where usable means isClean, isEmpty, hasChair.
class Table{
public boolean hasChair(){...}
public boolean isClean(){...}
public boolean isEmpty(){...}
}
I can implement my filtering test for my list List<Table> tablesList = Arrays.asList(table1,table2,table3,table4); in 2 ways: the first with boolean:
public boolean isUsable(){
return hasChair() && isClean() && isEmpty();
}
And use it with tablesList.stream().filter(Table::isUsable)
The second way is with predicate:
public Predicate<Table> isUsable(){
return table -> table.isEmpty() && table.isClean() && table.hasChair();
}
Usable with tablesList.stream().filter(isUsable())
Which is the correct implementation? Why choose one instead of other? Is there any big difference?

I think you meant for the second example
public static Predicate<Table> isUsable(){
return table -> table.isEmpty() && table.isClean() && table.hasChair();
}
Which might already suggest this form is likely to confuse the reader. Without static you could write table.isUsable() or Table::isUsable but it wouldn't do what you think.
Which is the correct implementation?
I would prefer the Table::isUsable as it can also be used as table.isUsable for an instance.
Why choose one instead of other?
I feel the first example is more natural and less confusing.
The second form is more useful for manipulating Predicates e.g. Predicate.or(Predicate)
Is there any big difference?
In this case, using a Stream is likely to be slower, but more importantly, more likely to confuse.
One advantage of the method returning a Predicate is it could be added to any class e.g. you can't alter Table for some reason.

Having Predicate<Table> isUsable() assumes that you would always require that logic to be used in places that require a Predicate<Table> instance, which is a limitation.
On the other hand, having boolean isUsable() gives you the flexibility of using Table::isUsable where a Predicate<Table> is required, or using Table::isUsable as implementation of some other functional interfaces (that matches the signature of that method) or directly calling t.isUsable() for a specific Table instance. Hence I find this alternative more useful.

static List<Predicate<Table>> predicateList = Arrays.asList(Table::hasChair, Table::isClean);
static boolean isUsable(Table table) {
return predicateList.stream().allMatch(p -> p.test(table));
}
use isUsable:
List<Table> tablesList = ...
Stream<Table> usableTables = tablesList.stream().filter(Table::isUsable);

Related

Java Optional params good practice [duplicate]

Having been using Java 8 now for 6+ months or so, I'm pretty happy with the new API changes. One area I'm still not confident in is when to use Optional. I seem to swing between wanting to use it everywhere something may be null, and nowhere at all.
There seem to be a lot of situations when I could use it, and I'm never sure if it adds benefits (readability / null safety) or just causes additional overhead.
So, I have a few examples, and I'd be interested in the community's thoughts on whether Optional is beneficial.
1 - As a public method return type when the method could return null:
public Optional<Foo> findFoo(String id);
2 - As a method parameter when the param may be null:
public Foo doSomething(String id, Optional<Bar> barOptional);
3 - As an optional member of a bean:
public class Book {
private List<Pages> pages;
private Optional<Index> index;
}
4 - In Collections:
In general I don't think:
List<Optional<Foo>>
adds anything - especially since one can use filter() to remove null values etc, but are there any good uses for Optional in collections?
Any cases I've missed?
The main design goal of Optional is to provide a means for a function returning a value to indicate the absence of a return value. See this discussion. This allows the caller to continue a chain of fluent method calls.
This most closely matches use case #1 in the OP's question. Although, absence of a value is a more precise formulation than null since something like IntStream.findFirst could never return null.
For use case #2, passing an optional argument to a method, this could be made to work, but it's rather clumsy. Suppose you have a method that takes a string followed by an optional second string. Accepting an Optional as the second arg would result in code like this:
foo("bar", Optional.of("baz"));
foo("bar", Optional.empty());
Even accepting null is nicer:
foo("bar", "baz");
foo("bar", null);
Probably the best is to have an overloaded method that accepts a single string argument and provides a default for the second:
foo("bar", "baz");
foo("bar");
This does have limitations, but it's much nicer than either of the above.
Use cases #3 and #4, having an Optional in a class field or in a data structure, is considered a misuse of the API. First, it goes against the main design goal of Optional as stated at the top. Second, it doesn't add any value.
There are three ways to deal with the absence of a value in an Optional: to provide a substitute value, to call a function to provide a substitute value, or to throw an exception. If you're storing into a field, you'd do this at initialization or assignment time. If you're adding values into a list, as the OP mentioned, you have the additional choice of simply not adding the value, thereby "flattening" out absent values.
I'm sure somebody could come up with some contrived cases where they really want to store an Optional in a field or a collection, but in general, it is best to avoid doing this.
I'm late to the game but for what it's worth, I want to add my 2 Cents. They go against the design goal of Optional, which is well summarized by Stuart Marks's answer, but I'm still convinced of their validity (obviously).
Use Optional Everywhere
In General
I wrote an entire blog post about using Optional but it basically comes down to this:
design your classes to avoid optionality wherever feasibly possible
in all remaining cases, the default should be to use Optional instead of null
possibly make exceptions for:
local variables
return values and arguments to private methods
performance critical code blocks (no guesses, use a profiler)
The first two exceptions can reduce the perceived overhead of wrapping and unwrapping references in Optional. They are chosen such that a null can never legally pass a boundary from one instance into another.
Note that this will almost never allow Optionals in collections which is almost as bad as nulls. Just don't do it. ;)
Regarding your questions
Yes.
If overloading is no option, yes.
If other approaches (subclassing, decorating, ...) are no option, yes.
Please no!
Advantages
Doing this reduces the presence of nulls in your code base, although it does not eradicate them. But that is not even the main point. There are other important advantages:
Clarifies Intent
Using Optional clearly expresses that the variable is, well, optional. Any reader of your code or consumer of your API will be beaten over the head with the fact that there might be nothing there and that a check is necessary before accessing the value.
Removes Uncertainty
Without Optional the meaning of a null occurrence is unclear. It could be a legal representation of a state (see Map.get) or an implementation error like a missing or failed initialization.
This changes dramatically with the persistent use of Optional. Here, already the occurrence of null signifies the presence of a bug. (Because if the value were allowed to be missing, an Optional would have been used.) This makes debugging a null pointer exception much easier as the question of the meaning of this null is already answered.
More Null Checks
Now that nothing can be null anymore, this can be enforced everywhere. Whether with annotations, assertions or plain checks, you never have to think about whether this argument or that return type can be null. It can't!
Disadvantages
Of course, there is no silver bullet...
Performance
Wrapping values (especially primitives) into an extra instance can degrade performance. In tight loops this might become noticeable or even worse.
Note that the compiler might be able to circumvent the extra reference for short lived lifetimes of Optionals. In Java 10 value types might further reduce or remove the penalty.
Serialization
Optional is not serializable but a workaround is not overly complicated.
Invariance
Due to the invariance of generic types in Java, certain operations become cumbersome when the actual value type is pushed into a generic type argument. An example is given here (see "Parametric polymorphism").
Personally, I prefer to use IntelliJ's Code Inspection Tool to use #NotNull and #Nullable checks as these are largely compile time (can have some runtime checks) This has lower overhead in terms of code readability and runtime performance. It is not as rigorous as using Optional, however this lack of rigour should be backed by decent unit tests.
public #Nullable Foo findFoo(#NotNull String id);
public #NotNull Foo doSomething(#NotNull String id, #Nullable Bar barOptional);
public class Book {
private List<Pages> pages;
private #Nullable Index index;
}
List<#Nullable Foo> list = ..
This works with Java 5 and no need to wrap and unwrap values. (or create wrapper objects)
I think the Guava Optional and their wiki page puts it quite well:
Besides the increase in readability that comes from giving null a name, the biggest advantage of Optional is its idiot-proof-ness. It forces you to actively think about the absent case if you want your program to compile at all, since you have to actively unwrap the Optional and address that case. Null makes it disturbingly easy to simply forget things, and though FindBugs helps, we don't think it addresses the issue nearly as well.
This is especially relevant when you're returning values that may or may not be "present." You (and others) are far more likely to forget that other.method(a, b) could return a null value than you're likely to forget that a could be null when you're implementing other.method. Returning Optional makes it impossible for callers to forget that case, since they have to unwrap the object themselves for their code to compile.
-- (Source: Guava Wiki - Using and Avoiding null - What's the point?)
Optional adds some overhead, but I think its clear advantage is to make it explicit
that an object might be absent and it enforces that programmers handle the situation. It prevents that someone forgets the beloved != null check.
Taking the example of 2, I think it is far more explicit code to write:
if(soundcard.isPresent()){
System.out.println(soundcard.get());
}
than
if(soundcard != null){
System.out.println(soundcard);
}
For me, the Optional better captures the fact that there is no soundcard present.
My 2¢ about your points:
public Optional<Foo> findFoo(String id); - I am not sure about this. Maybe I would return a Result<Foo> which might be empty or contain a Foo. It is a similar concept, but not really an Optional.
public Foo doSomething(String id, Optional<Bar> barOptional); - I would prefer #Nullable and a findbugs check, as in Peter Lawrey's answer - see also this discussion.
Your book example - I am not sure if I would use the Optional internally, that might depend on the complexity. For the "API" of a book, I would use an Optional<Index> getIndex() to explicitly indicate that the book might not have an index.
I would not use it in collections, rather not allowing null values in collections
In general, I would try to minimize passing around nulls. (Once burnt...)
I think it is worth to find the appropriate abstractions and indicate to the fellow programmers what a certain return value actually represents.
From Oracle tutorial:
The purpose of Optional is not to replace every single null reference in your codebase but rather to help design better APIs in which—just by reading the signature of a method—users can tell whether to expect an optional value. In addition, Optional forces you to actively unwrap an Optional to deal with the absence of a value; as a result, you protect your code against unintended null pointer exceptions.
In java, just don't use them unless you are addicted to functional programming.
They have no place as method arguments (I promess someone one day will pass you a null optional, not just an optional that is empty).
They make sense for return values but they invite the client class to keep on stretching the behavior-building chain.
FP and chains have little place in an imperative language like java because it makes it very hard to debug, not just to read. When you step to the line, you can't know the state nor intent of the program; you have to step into to figure it out (into code that often isn't yours and many stack frames deep despite step filters) and you have to add lots of breakpoints down to make sure it can stop in the code/lambda you added, instead of simply walking the if/else/call trivial lines.
If you want functional programming, pick something else than java and hope you have the tools for debugging that.
1 - As a public method return type when the method could return null:
Here is a good article that shows usefulness of usecase #1. There this code
...
if (user != null) {
Address address = user.getAddress();
if (address != null) {
Country country = address.getCountry();
if (country != null) {
String isocode = country.getIsocode();
isocode = isocode.toUpperCase();
}
}
}
...
is transformed to this
String result = Optional.ofNullable(user)
.flatMap(User::getAddress)
.flatMap(Address::getCountry)
.map(Country::getIsocode)
.orElse("default");
by using Optional as a return value of respective getter methods.
Here is an interesting usage (I believe) for... Tests.
I intend to heavily test one of my projects and I therefore build assertions; only there are things I have to verify and others I don't.
I therefore build things to assert and use an assert to verify them, like this:
public final class NodeDescriptor<V>
{
private final Optional<String> label;
private final List<NodeDescriptor<V>> children;
private NodeDescriptor(final Builder<V> builder)
{
label = Optional.fromNullable(builder.label);
final ImmutableList.Builder<NodeDescriptor<V>> listBuilder
= ImmutableList.builder();
for (final Builder<V> element: builder.children)
listBuilder.add(element.build());
children = listBuilder.build();
}
public static <E> Builder<E> newBuilder()
{
return new Builder<E>();
}
public void verify(#Nonnull final Node<V> node)
{
final NodeAssert<V> nodeAssert = new NodeAssert<V>(node);
nodeAssert.hasLabel(label);
}
public static final class Builder<V>
{
private String label;
private final List<Builder<V>> children = Lists.newArrayList();
private Builder()
{
}
public Builder<V> withLabel(#Nonnull final String label)
{
this.label = Preconditions.checkNotNull(label);
return this;
}
public Builder<V> withChildNode(#Nonnull final Builder<V> child)
{
Preconditions.checkNotNull(child);
children.add(child);
return this;
}
public NodeDescriptor<V> build()
{
return new NodeDescriptor<V>(this);
}
}
}
In the NodeAssert class, I do this:
public final class NodeAssert<V>
extends AbstractAssert<NodeAssert<V>, Node<V>>
{
NodeAssert(final Node<V> actual)
{
super(Preconditions.checkNotNull(actual), NodeAssert.class);
}
private NodeAssert<V> hasLabel(final String label)
{
final String thisLabel = actual.getLabel();
assertThat(thisLabel).overridingErrorMessage(
"node's label is null! I didn't expect it to be"
).isNotNull();
assertThat(thisLabel).overridingErrorMessage(
"node's label is not what was expected!\n"
+ "Expected: '%s'\nActual : '%s'\n", label, thisLabel
).isEqualTo(label);
return this;
}
NodeAssert<V> hasLabel(#Nonnull final Optional<String> label)
{
return label.isPresent() ? hasLabel(label.get()) : this;
}
}
Which means the assert really only triggers if I want to check the label!
Optional class lets you avoid to use null and provide a better alternative:
This encourages the developer to make checks for presence in order to avoid uncaught NullPointerException's.
API becomes better documented because it's possible to see, where to expect the values which can be absent.
Optional provides convenient API for further work with the object:
isPresent(); get(); orElse(); orElseGet(); orElseThrow(); map(); filter(); flatmap().
In addition, many frameworks actively use this data type and return it from their API.
An Optional has similar semantics to an unmodifiable instance of the Iterator design pattern:
it might or might not refer to an object (as given by isPresent())
it can be dereferenced (using get()) if it does refer to an object
but it can not be advanced to the next position in the sequence (it has no next() method).
Therefore consider returning or passing an Optional in contexts where you might previously have considered using a Java Iterator.
Here are some of the methods that you can perform on an instance of Optional<T>:
map
flatMap
orElse
orElseThrow
ifPresentOrElse
get
Here are all the methods that you can perform on null:
(there are none)
This is really an apples to oranges comparison: Optional<T> is an actual instance of an object (unless it is null… but that would probably be a bug) while null is an aborted object. All you can do with null is check whether it is in fact null, or not. So if you like to use methods on objects, Optional<T> is for you; if you like to branch on special literals, null is for you.
null does not compose. You simply can’t compose a value which you can only branch on. But Optional<T> does compose.
You can, for instance, make arbitrary long chains of “apply this function if non-empty” by using map. Or you can effectively make an imperative block of code which consumes the optional if it is non-empty by using ifPresent. Or you can make an “if/else” by using ifPresentOrElse, which consumes the non-empty optional if it is non-empty or else executes some other code.
…And it is at this point that we run into the true limitations of the language in my opinion: for very imperative code you have to wrap them in lambdas and pass them to methods:
opt.ifPresentOrElse(
string -> { // if present...
// ...
}, () -> { // or else...
// ...
}
);
That might not be good enough for some people, style-wise.
It would be more seamless if Optional<T> was an algebraic data type that we could pattern match on (this is obviously pseudo-code:
match (opt) {
Present(str) => {
// ...
}
Empty =>{
// ...
}
}
But anyway, in summary: Optional<T> is a pretty robust empty-or-present object. null is just a sentinel value.
Subjectively disregarded reasons
There seems to be a few people who effectively argue that efficiency should determine whether one should use Optional<T> or branch on the null sentinel value. That seems a bit like making hard and fast rules on when to make objects rather than primitives in the general case. I think it’s a bit ridiculous to use that as the starting point for this discussion when you’re already working in a language where it’s idiomatic to make objects left-and-right, top to bottom, all the time (in my opinion).
I do not think that Optional is a general substitute for methods that potentially return null values.
The basic idea is: The absence of a value does not mean that it potentially is available in the future. It's a difference between findById(-1) and findById(67).
The main information of Optionals for the caller is that he may not count on the value given but it may be available at some time. Maybe it will disappear again and comes back later one more time. It's like an on/off switch. You have the "option" to switch the light on or off. But you have no option if you do not have a light to switch on.
So I find it too messy to introduce Optionals everywhere where previously null was potentially returned. I will still use null, but only in restricted areas like the root of a tree, lazy initialization and explicit find-methods.
Seems Optional is only useful if the type T in Optional is a primitive type like int, long, char, etc. For "real" classes, it does not make sense to me as you can use a null value anyway.
I think it was taken from here (or from another similar language concept).
Nullable<T>
In C# this Nullable<T> was introduced long ago to wrap value types.
1 - As a public method return type when the method could return null:
This is the intended use case for Optional, as seen in the JDK API docs:
Optional is primarily intended for use as a method return type where
there is a clear need to represent "no result," and where using null
is likely to cause errors.
Optional represents one of two states:
it has a value (isPresent returns true)
it doesn't have a value (isEmpty returns true)
So if you have a method that returns either something or nothing, this is the ideal use case for Optional.
Here's an example:
Optional<Guitarist> findByLastName(String lastName);
This method takes a parameter used to search for an entity in the database. It's possible that no such entity exists, so using an Optional return type is a good idea since it forces whoever is calling the method to consider the empty scenario. This reduces chances of a NullPointerException.
2 - As a method parameter when the param may be null:
Although technically possible, this is not the intended use case of Optional.
Let's consider your proposed method signature:
public Foo doSomething(String id, Optional<Bar> barOptional);
The main problem is that we could call doSomething where barOptional has one of 3 states:
an Optional with a value e.g. doSomething("123", Optional.of(new Bar())
an empty Optional e.g. doSomething("123", Optional.empty())
null e.g. doSomething("123", null)
These 3 states would need to be handled in the method implementation appropriately.
A better solution is to implement an overloaded method.
public Foo doSomething(String id);
public Foo doSomething(String id, Bar bar);
This makes it very clear to the consumer of the API which method to call, and null does not need to be passed.
3 - As an optional member of a bean:
Given your example Book class:
public class Book {
private List<Pages> pages;
private Optional<Index> index;
}
The Optional class variable suffers from the same issue as the Optional method parameter discussed above. It can have one of 3 states: present, empty, or null.
Other possible issues include:
serialization: if you implement Serializable and try to serialize an object of this class, you will encounter a java.io.NotSerializableException since Optional was not designed for this use case
transforming to JSON: when serializing to JSON an Optional field may get mapped in an undesirable way e.g. {"empty":false,"present":true}.
Although if you use the popular Jackson library, it does provide a solution to this problem.
Despite these issues, Oracle themselves published this blog post at the time of the Java 8 Optional release in 2014. It contains code examples using Optional for class variables.
public class Computer {
private Optional<Soundcard> soundcard;
public Optional<Soundcard> getSoundcard() { ... }
...
}
In the following years though, developers have found better alternatives such as implementing a getter method to create the Optional object.
public class Book {
private List<Pages> pages;
private Index index;
public Optional<Index> getIndex() {
return Optional.ofNullable(index);
}
}
Here we use the ofNullable method to return an Optional with a value if index is non-null, or otherwise an empty Optional.
4 - In Collections:
I agree that creating a List of Optional (e.g. List<Optional<Foo>>) doesn't add anything.
Instead, just don't include the item in the List if it's not present.

Why use lambda over normal methods?

So suppose my application does lots of repetitive work, for example let's say my application checks lots of various Lists if they're empty or not. There are two methods by which I can accomplish this functionality - (there maybe other methods but since my goal is to understand the difference of the two methods and not the functionality itself here we go)
Method 1 - Tradition Method
public boolean isEmptyOrNull(List list)
{
return list != null && !list.isEmpty();
}
Method 2 - Lambda Way
Assuming we have created a functional interface with class name Demo and boolean isEmptyOrNull as the function.
Demo var = list -> list != null && !list.isEmpty();
So each time I wish to check a list I can either use Method 1 or 2 by using isEmptyOrNull(myList) or var.isEmptyOrNull(myList) respectively.
My question is why should I use Method 1 and not Method 2 and vice versa. Is there some performance aspect or some other aspect as to why I should prefer one method over the other !?
Oof, where to start.
Your idea of what null is, is broken.
isEmptyOrNull is a code smell. You shouldn't have this method.
null is a stand-in value that necessarily can mean 'not initialised', because that's built into java itself: Any field that you don't explicitly set will be null. However, it is very common in APIs, even in java.* APIs, that null can also mean 'not found' (such as when you call map.get(someKeyNotInTheMap)), and sometimes also 'irrelevant in this context', such as asking a bootstrapped class for its ClassLoader.
It does not, as a rule, mean 'empty'. That's because there is a perfectly fine non-null value that does a perfect job representing empty. For strings, "" is the empty string, so use that, don't arbitrarily return null instead. For lists, an empty list (as easy to make as List.of()) is what you should be using for empty lists.
Assuming that null semantically means the exact same thing as List.of() is either unneccessary (the source of that list wouldn't be returning null in the first place, thus making that null check unneccessary) or worse, will hide errors: You erroneously interpret 'uninitialized' as 'empty', which is a fine way to have a bug and to have that result your app doing nothing, making it very hard to find the bug. It's much better if a bug loudly announces its presence and does so by pointing exactly at the place in your code where the bug exists, which is why you want an exception instead of a 'do nothing, silently, when that is incorrect' style bug.
Your lambda code does not compile
Unless Demo is a functional interface that has the method boolean isEmptyOrNull(List list);, that is.
The difference
The crucial difference is that a lambda represents a method that you can reference. You can pass the lambda itself around as a parameter.
For example, java.util.TreeSet is an implementation of set that stores all elements you put inside in sorted order by using a tree. It's like building a phonebook: To put "Ms. Bernstein" into the phonebook, you open the book to the middle, check the name there, and if it's 'above' 'Bernstein', look at the middle of the first half. Keep going until you find the place where Bernstein should be inserted; even in a phonebook of a million numbers, this only takes about 20 steps, which is why TreeSet is fast even if you put tons of stuff in there.
The one thing TreeSet needs to do its job is a comparison function: "Given the name 'Maidstone' and 'Bernstein', which one should be listed later in the phone book"? That's all. If you have that function then TreeSet can do its job regardless of the kind of object you store in it.
So let's say you want to make a phone book that first sorts on the length of names, and only then alphabetically.
This requires that you pass the function that decrees which of two names is 'after' the other. Lambdas make this easy:
Comparator<String> decider = (a, b) -> {
if (a.length() < b.length()) return -1;
if (a.length() > b.length()) return +1;
return a.compareTo(b);
};
SortedSet<String> phonebook = new TreeSet<>(decider);
Now try to write this without using lambdas. You won't be able to, as you can't use method names like this. This doesn't work:
public void decider(String a, String b) {
if (a.length() < b.length()) return -1;
if (a.length() > b.length()) return +1;
return a.compareTo(b);
}
public SortedSet<String> makeLengthBook() {
return new TreeSet<String>(decider);
}
There are many reasons that doesn't work, but from a language design point of view: Because in java you can have a method named decider, and also a local variable named decider. You can write this::decider which would work - that's just syntax sugar for (a, b) -> this.decider(a, b); and you should by all means use that where possible.
There is no advantage in your example. Lamdas are often used in Object Streams, e.g for mapping or filtering by defining "adhoc functions" (that's what lambdas are).
Example: You have a list of strings named allStrings that you want to filter
List<String> longStrings = allStrings.stream()
.filter(s -> s.length() > 5) // only keep strings longer than 5
.collect(Collectors.toList()); // collect stream in a new list
Lambdas were added to introduce functional programming in java. It could be used as a shorthand for implementing single method interfaces (Functional interfaces). In the above example you provided, there is no much advantage. But lambdas could be useful in the below scenario:
Before lambdas
public Interface Calc{
int doCalc(int a, int b);
}
public class MyClass{
public void main(String[] args){
Calc x = new Calc() {
#Override
public int doCalc(int a, int b) {
return a + b;
}
};
System.out.println(x.doCalc(2, 3));
}
}
But with lambdas this could be simplified to
public class MyClass{
public void main(String[] args){
BiFunction<Integer, Integer, Integer> doCalc= (a, b) -> a + b;
System.out.println(doCalc.apply(2, 3));
}
}
This is especially helpful for implementing event listeners (in Android), in which case there are a lot of interfaces provided as part of the API with methods like onClick etc. In such cases lambdas could be useful to reduce the code.
Also with Java 8, streams were introduced and lambdas could be passed to filter/map the stream elements. Stream allow more readable code than traditional for loop / if-else in most cases.

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.

Uses for Optional

Having been using Java 8 now for 6+ months or so, I'm pretty happy with the new API changes. One area I'm still not confident in is when to use Optional. I seem to swing between wanting to use it everywhere something may be null, and nowhere at all.
There seem to be a lot of situations when I could use it, and I'm never sure if it adds benefits (readability / null safety) or just causes additional overhead.
So, I have a few examples, and I'd be interested in the community's thoughts on whether Optional is beneficial.
1 - As a public method return type when the method could return null:
public Optional<Foo> findFoo(String id);
2 - As a method parameter when the param may be null:
public Foo doSomething(String id, Optional<Bar> barOptional);
3 - As an optional member of a bean:
public class Book {
private List<Pages> pages;
private Optional<Index> index;
}
4 - In Collections:
In general I don't think:
List<Optional<Foo>>
adds anything - especially since one can use filter() to remove null values etc, but are there any good uses for Optional in collections?
Any cases I've missed?
The main design goal of Optional is to provide a means for a function returning a value to indicate the absence of a return value. See this discussion. This allows the caller to continue a chain of fluent method calls.
This most closely matches use case #1 in the OP's question. Although, absence of a value is a more precise formulation than null since something like IntStream.findFirst could never return null.
For use case #2, passing an optional argument to a method, this could be made to work, but it's rather clumsy. Suppose you have a method that takes a string followed by an optional second string. Accepting an Optional as the second arg would result in code like this:
foo("bar", Optional.of("baz"));
foo("bar", Optional.empty());
Even accepting null is nicer:
foo("bar", "baz");
foo("bar", null);
Probably the best is to have an overloaded method that accepts a single string argument and provides a default for the second:
foo("bar", "baz");
foo("bar");
This does have limitations, but it's much nicer than either of the above.
Use cases #3 and #4, having an Optional in a class field or in a data structure, is considered a misuse of the API. First, it goes against the main design goal of Optional as stated at the top. Second, it doesn't add any value.
There are three ways to deal with the absence of a value in an Optional: to provide a substitute value, to call a function to provide a substitute value, or to throw an exception. If you're storing into a field, you'd do this at initialization or assignment time. If you're adding values into a list, as the OP mentioned, you have the additional choice of simply not adding the value, thereby "flattening" out absent values.
I'm sure somebody could come up with some contrived cases where they really want to store an Optional in a field or a collection, but in general, it is best to avoid doing this.
I'm late to the game but for what it's worth, I want to add my 2 Cents. They go against the design goal of Optional, which is well summarized by Stuart Marks's answer, but I'm still convinced of their validity (obviously).
Use Optional Everywhere
In General
I wrote an entire blog post about using Optional but it basically comes down to this:
design your classes to avoid optionality wherever feasibly possible
in all remaining cases, the default should be to use Optional instead of null
possibly make exceptions for:
local variables
return values and arguments to private methods
performance critical code blocks (no guesses, use a profiler)
The first two exceptions can reduce the perceived overhead of wrapping and unwrapping references in Optional. They are chosen such that a null can never legally pass a boundary from one instance into another.
Note that this will almost never allow Optionals in collections which is almost as bad as nulls. Just don't do it. ;)
Regarding your questions
Yes.
If overloading is no option, yes.
If other approaches (subclassing, decorating, ...) are no option, yes.
Please no!
Advantages
Doing this reduces the presence of nulls in your code base, although it does not eradicate them. But that is not even the main point. There are other important advantages:
Clarifies Intent
Using Optional clearly expresses that the variable is, well, optional. Any reader of your code or consumer of your API will be beaten over the head with the fact that there might be nothing there and that a check is necessary before accessing the value.
Removes Uncertainty
Without Optional the meaning of a null occurrence is unclear. It could be a legal representation of a state (see Map.get) or an implementation error like a missing or failed initialization.
This changes dramatically with the persistent use of Optional. Here, already the occurrence of null signifies the presence of a bug. (Because if the value were allowed to be missing, an Optional would have been used.) This makes debugging a null pointer exception much easier as the question of the meaning of this null is already answered.
More Null Checks
Now that nothing can be null anymore, this can be enforced everywhere. Whether with annotations, assertions or plain checks, you never have to think about whether this argument or that return type can be null. It can't!
Disadvantages
Of course, there is no silver bullet...
Performance
Wrapping values (especially primitives) into an extra instance can degrade performance. In tight loops this might become noticeable or even worse.
Note that the compiler might be able to circumvent the extra reference for short lived lifetimes of Optionals. In Java 10 value types might further reduce or remove the penalty.
Serialization
Optional is not serializable but a workaround is not overly complicated.
Invariance
Due to the invariance of generic types in Java, certain operations become cumbersome when the actual value type is pushed into a generic type argument. An example is given here (see "Parametric polymorphism").
Personally, I prefer to use IntelliJ's Code Inspection Tool to use #NotNull and #Nullable checks as these are largely compile time (can have some runtime checks) This has lower overhead in terms of code readability and runtime performance. It is not as rigorous as using Optional, however this lack of rigour should be backed by decent unit tests.
public #Nullable Foo findFoo(#NotNull String id);
public #NotNull Foo doSomething(#NotNull String id, #Nullable Bar barOptional);
public class Book {
private List<Pages> pages;
private #Nullable Index index;
}
List<#Nullable Foo> list = ..
This works with Java 5 and no need to wrap and unwrap values. (or create wrapper objects)
I think the Guava Optional and their wiki page puts it quite well:
Besides the increase in readability that comes from giving null a name, the biggest advantage of Optional is its idiot-proof-ness. It forces you to actively think about the absent case if you want your program to compile at all, since you have to actively unwrap the Optional and address that case. Null makes it disturbingly easy to simply forget things, and though FindBugs helps, we don't think it addresses the issue nearly as well.
This is especially relevant when you're returning values that may or may not be "present." You (and others) are far more likely to forget that other.method(a, b) could return a null value than you're likely to forget that a could be null when you're implementing other.method. Returning Optional makes it impossible for callers to forget that case, since they have to unwrap the object themselves for their code to compile.
-- (Source: Guava Wiki - Using and Avoiding null - What's the point?)
Optional adds some overhead, but I think its clear advantage is to make it explicit
that an object might be absent and it enforces that programmers handle the situation. It prevents that someone forgets the beloved != null check.
Taking the example of 2, I think it is far more explicit code to write:
if(soundcard.isPresent()){
System.out.println(soundcard.get());
}
than
if(soundcard != null){
System.out.println(soundcard);
}
For me, the Optional better captures the fact that there is no soundcard present.
My 2¢ about your points:
public Optional<Foo> findFoo(String id); - I am not sure about this. Maybe I would return a Result<Foo> which might be empty or contain a Foo. It is a similar concept, but not really an Optional.
public Foo doSomething(String id, Optional<Bar> barOptional); - I would prefer #Nullable and a findbugs check, as in Peter Lawrey's answer - see also this discussion.
Your book example - I am not sure if I would use the Optional internally, that might depend on the complexity. For the "API" of a book, I would use an Optional<Index> getIndex() to explicitly indicate that the book might not have an index.
I would not use it in collections, rather not allowing null values in collections
In general, I would try to minimize passing around nulls. (Once burnt...)
I think it is worth to find the appropriate abstractions and indicate to the fellow programmers what a certain return value actually represents.
From Oracle tutorial:
The purpose of Optional is not to replace every single null reference in your codebase but rather to help design better APIs in which—just by reading the signature of a method—users can tell whether to expect an optional value. In addition, Optional forces you to actively unwrap an Optional to deal with the absence of a value; as a result, you protect your code against unintended null pointer exceptions.
In java, just don't use them unless you are addicted to functional programming.
They have no place as method arguments (I promess someone one day will pass you a null optional, not just an optional that is empty).
They make sense for return values but they invite the client class to keep on stretching the behavior-building chain.
FP and chains have little place in an imperative language like java because it makes it very hard to debug, not just to read. When you step to the line, you can't know the state nor intent of the program; you have to step into to figure it out (into code that often isn't yours and many stack frames deep despite step filters) and you have to add lots of breakpoints down to make sure it can stop in the code/lambda you added, instead of simply walking the if/else/call trivial lines.
If you want functional programming, pick something else than java and hope you have the tools for debugging that.
1 - As a public method return type when the method could return null:
Here is a good article that shows usefulness of usecase #1. There this code
...
if (user != null) {
Address address = user.getAddress();
if (address != null) {
Country country = address.getCountry();
if (country != null) {
String isocode = country.getIsocode();
isocode = isocode.toUpperCase();
}
}
}
...
is transformed to this
String result = Optional.ofNullable(user)
.flatMap(User::getAddress)
.flatMap(Address::getCountry)
.map(Country::getIsocode)
.orElse("default");
by using Optional as a return value of respective getter methods.
Here is an interesting usage (I believe) for... Tests.
I intend to heavily test one of my projects and I therefore build assertions; only there are things I have to verify and others I don't.
I therefore build things to assert and use an assert to verify them, like this:
public final class NodeDescriptor<V>
{
private final Optional<String> label;
private final List<NodeDescriptor<V>> children;
private NodeDescriptor(final Builder<V> builder)
{
label = Optional.fromNullable(builder.label);
final ImmutableList.Builder<NodeDescriptor<V>> listBuilder
= ImmutableList.builder();
for (final Builder<V> element: builder.children)
listBuilder.add(element.build());
children = listBuilder.build();
}
public static <E> Builder<E> newBuilder()
{
return new Builder<E>();
}
public void verify(#Nonnull final Node<V> node)
{
final NodeAssert<V> nodeAssert = new NodeAssert<V>(node);
nodeAssert.hasLabel(label);
}
public static final class Builder<V>
{
private String label;
private final List<Builder<V>> children = Lists.newArrayList();
private Builder()
{
}
public Builder<V> withLabel(#Nonnull final String label)
{
this.label = Preconditions.checkNotNull(label);
return this;
}
public Builder<V> withChildNode(#Nonnull final Builder<V> child)
{
Preconditions.checkNotNull(child);
children.add(child);
return this;
}
public NodeDescriptor<V> build()
{
return new NodeDescriptor<V>(this);
}
}
}
In the NodeAssert class, I do this:
public final class NodeAssert<V>
extends AbstractAssert<NodeAssert<V>, Node<V>>
{
NodeAssert(final Node<V> actual)
{
super(Preconditions.checkNotNull(actual), NodeAssert.class);
}
private NodeAssert<V> hasLabel(final String label)
{
final String thisLabel = actual.getLabel();
assertThat(thisLabel).overridingErrorMessage(
"node's label is null! I didn't expect it to be"
).isNotNull();
assertThat(thisLabel).overridingErrorMessage(
"node's label is not what was expected!\n"
+ "Expected: '%s'\nActual : '%s'\n", label, thisLabel
).isEqualTo(label);
return this;
}
NodeAssert<V> hasLabel(#Nonnull final Optional<String> label)
{
return label.isPresent() ? hasLabel(label.get()) : this;
}
}
Which means the assert really only triggers if I want to check the label!
Optional class lets you avoid to use null and provide a better alternative:
This encourages the developer to make checks for presence in order to avoid uncaught NullPointerException's.
API becomes better documented because it's possible to see, where to expect the values which can be absent.
Optional provides convenient API for further work with the object:
isPresent(); get(); orElse(); orElseGet(); orElseThrow(); map(); filter(); flatmap().
In addition, many frameworks actively use this data type and return it from their API.
An Optional has similar semantics to an unmodifiable instance of the Iterator design pattern:
it might or might not refer to an object (as given by isPresent())
it can be dereferenced (using get()) if it does refer to an object
but it can not be advanced to the next position in the sequence (it has no next() method).
Therefore consider returning or passing an Optional in contexts where you might previously have considered using a Java Iterator.
Here are some of the methods that you can perform on an instance of Optional<T>:
map
flatMap
orElse
orElseThrow
ifPresentOrElse
get
Here are all the methods that you can perform on null:
(there are none)
This is really an apples to oranges comparison: Optional<T> is an actual instance of an object (unless it is null… but that would probably be a bug) while null is an aborted object. All you can do with null is check whether it is in fact null, or not. So if you like to use methods on objects, Optional<T> is for you; if you like to branch on special literals, null is for you.
null does not compose. You simply can’t compose a value which you can only branch on. But Optional<T> does compose.
You can, for instance, make arbitrary long chains of “apply this function if non-empty” by using map. Or you can effectively make an imperative block of code which consumes the optional if it is non-empty by using ifPresent. Or you can make an “if/else” by using ifPresentOrElse, which consumes the non-empty optional if it is non-empty or else executes some other code.
…And it is at this point that we run into the true limitations of the language in my opinion: for very imperative code you have to wrap them in lambdas and pass them to methods:
opt.ifPresentOrElse(
string -> { // if present...
// ...
}, () -> { // or else...
// ...
}
);
That might not be good enough for some people, style-wise.
It would be more seamless if Optional<T> was an algebraic data type that we could pattern match on (this is obviously pseudo-code:
match (opt) {
Present(str) => {
// ...
}
Empty =>{
// ...
}
}
But anyway, in summary: Optional<T> is a pretty robust empty-or-present object. null is just a sentinel value.
Subjectively disregarded reasons
There seems to be a few people who effectively argue that efficiency should determine whether one should use Optional<T> or branch on the null sentinel value. That seems a bit like making hard and fast rules on when to make objects rather than primitives in the general case. I think it’s a bit ridiculous to use that as the starting point for this discussion when you’re already working in a language where it’s idiomatic to make objects left-and-right, top to bottom, all the time (in my opinion).
I do not think that Optional is a general substitute for methods that potentially return null values.
The basic idea is: The absence of a value does not mean that it potentially is available in the future. It's a difference between findById(-1) and findById(67).
The main information of Optionals for the caller is that he may not count on the value given but it may be available at some time. Maybe it will disappear again and comes back later one more time. It's like an on/off switch. You have the "option" to switch the light on or off. But you have no option if you do not have a light to switch on.
So I find it too messy to introduce Optionals everywhere where previously null was potentially returned. I will still use null, but only in restricted areas like the root of a tree, lazy initialization and explicit find-methods.
Seems Optional is only useful if the type T in Optional is a primitive type like int, long, char, etc. For "real" classes, it does not make sense to me as you can use a null value anyway.
I think it was taken from here (or from another similar language concept).
Nullable<T>
In C# this Nullable<T> was introduced long ago to wrap value types.
1 - As a public method return type when the method could return null:
This is the intended use case for Optional, as seen in the JDK API docs:
Optional is primarily intended for use as a method return type where
there is a clear need to represent "no result," and where using null
is likely to cause errors.
Optional represents one of two states:
it has a value (isPresent returns true)
it doesn't have a value (isEmpty returns true)
So if you have a method that returns either something or nothing, this is the ideal use case for Optional.
Here's an example:
Optional<Guitarist> findByLastName(String lastName);
This method takes a parameter used to search for an entity in the database. It's possible that no such entity exists, so using an Optional return type is a good idea since it forces whoever is calling the method to consider the empty scenario. This reduces chances of a NullPointerException.
2 - As a method parameter when the param may be null:
Although technically possible, this is not the intended use case of Optional.
Let's consider your proposed method signature:
public Foo doSomething(String id, Optional<Bar> barOptional);
The main problem is that we could call doSomething where barOptional has one of 3 states:
an Optional with a value e.g. doSomething("123", Optional.of(new Bar())
an empty Optional e.g. doSomething("123", Optional.empty())
null e.g. doSomething("123", null)
These 3 states would need to be handled in the method implementation appropriately.
A better solution is to implement an overloaded method.
public Foo doSomething(String id);
public Foo doSomething(String id, Bar bar);
This makes it very clear to the consumer of the API which method to call, and null does not need to be passed.
3 - As an optional member of a bean:
Given your example Book class:
public class Book {
private List<Pages> pages;
private Optional<Index> index;
}
The Optional class variable suffers from the same issue as the Optional method parameter discussed above. It can have one of 3 states: present, empty, or null.
Other possible issues include:
serialization: if you implement Serializable and try to serialize an object of this class, you will encounter a java.io.NotSerializableException since Optional was not designed for this use case
transforming to JSON: when serializing to JSON an Optional field may get mapped in an undesirable way e.g. {"empty":false,"present":true}.
Although if you use the popular Jackson library, it does provide a solution to this problem.
Despite these issues, Oracle themselves published this blog post at the time of the Java 8 Optional release in 2014. It contains code examples using Optional for class variables.
public class Computer {
private Optional<Soundcard> soundcard;
public Optional<Soundcard> getSoundcard() { ... }
...
}
In the following years though, developers have found better alternatives such as implementing a getter method to create the Optional object.
public class Book {
private List<Pages> pages;
private Index index;
public Optional<Index> getIndex() {
return Optional.ofNullable(index);
}
}
Here we use the ofNullable method to return an Optional with a value if index is non-null, or otherwise an empty Optional.
4 - In Collections:
I agree that creating a List of Optional (e.g. List<Optional<Foo>>) doesn't add anything.
Instead, just don't include the item in the List if it's not present.

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