Returning more than one value
Java has no tuples. Which is mostly fine, because the workaround is better than a tuple.
A Java method returns one value. When you want two, the options are not equal.
A record — the right answer
record MinMax(int min, int max) { }
MinMax range(int[] values) {
...
return new MinMax(lo, hi);
}
The caller gets named accessors:
MinMax r = range(data);
System.out.println(r.min());
This is better than a tuple would be, because the parts have names. pair.getFirst() tells the reader nothing; r.min() tells them everything. The declaration is one line, and you get equals, hashCode and toString free.
Before records, the same thing as a small class with two final fields — more typing, identical idea.
An array — usually a mistake
int[] range(int[] values) {
return new int[] { lo, hi };
}
Short to write, unpleasant to use. The caller has to know that [0] is the minimum, nothing enforces it, and swapping them is a silent bug. It also forces both values to share a type.
Acceptable in a private helper five lines from its only caller. Not in an API.
Modifying a parameter — no
Java is pass-by-value throughout. Reassigning a parameter inside a method changes nothing for the caller:
void bad(int x) { x = 99; } // caller's variable is untouched
Object references are also passed by value: you can modify the object a reference points at, but reassigning the parameter does not affect the caller’s variable. So “out parameters” as C or C# have them do not exist. Passing a mutable holder to be filled in works, and is worse than returning a record.
Optional, for absence
If the second value is really “did this succeed”, the answer may be one value that might not be there:
Optional<Customer> findById(String id);
Use Optional as a return type, not as a field or a parameter.
Two methods
If callers usually want one or the other, two methods are often clearer than one returning both. min(values) and max(values) read better than range(values).min() — unless computing them together is meaningfully cheaper, which for a single pass it can be.
Three or more
If a method wants to return four unrelated values, that is usually a sign it does more than one thing. Splitting it is a better fix than a wider record.