Reputation: 5660
Firstly, there are bunch of questions on stackoverflow on null pointers - but could not find this one. It it existed and i did not find it then please spare my mistake.
Question is generic - if a function returns just one element then how to deal with missing 'element' case. Eg: the sample code is just a sample.
public int findSmallestNumberGreaterThanX(int a[], int x) {
// do what ever logic.
if (numFound) { return smallesNumberGreaterThanX; }
else {
// what ??
}
}
If there was no number in array greater than x - what to do ?
Effective java mentions return empty array instead of null pointer - but is it worth creating an array if function returns single element ?
Next option is return null. I have seen bunch of posts which reject the idea of returning null.
Third is to return an object { boolean found; int value; } . This sounds like an overkill.
Please suggest me a best approach here.
Upvotes: 3
Views: 202
Reputation: 425083
It's very common to return null for a "not found" result. Returning a "special" value, such as Integer.MIN_VALUE
is OK, because mathematically that is not a legitimate result, but it would be an unconventional approach for the caller to dealt with.
You have two options:
Option 1. is generally not a good idea, but if you absolutely must return an int then use it
Option 2. is the more common solution, documented with javadoc
/**
* @returns null if not found
*/
public Integer findSmallestNumberGreaterThanX(int a[], int x) {
// do what ever logic.
if (numFound)
return smallesNumberGreaterThanX;
return null;
}
Upvotes: 0
Reputation: 63379
Another solution not yet mentioned is to have a special class representing values with failures. In one of our projects we had
public interface Option<T>
extends java.util.Collection<T>
{
// Throws an exception if empty.
public T get();
// Returns `deflt` if empty.
public T getOrElse(T deflt);
public boolean isEmpty();
}
Option
represents either a single value of type T
or no value. (It implements Collection
so that it can be viewed as a collection of 0 or 1 elements, which allows you to use it for example in for
comprehensions, but it's probably not important for your case.) It had two subclasses, one representing an empty Option
and one representing a full one:
// ---
public final class None<T>
extends AbstractCollection<T>
implements Option<T>
{
public None() {}
// ...
}
and
public final class Some<T>
extends AbstractCollection<T>
implements Option<T>
{
private final T value;
public Some(T value) {
this.value = value;
}
// ...
}
Full code available here.
It is just a variant of Scala's Option
class.
In your case you'd use it as
public Option<Integer> findSmallestNumberGreaterThanX(int a[], int x) {
// do what ever logic.
if (numFound) { return new Some<Integer>(smallesNumberGreaterThanX); }
else { return new None<Integer>(); }
}
Creating such an object has negligible overhead (unless you create millions of them), and gives a nice semantic distinction between a successful and a failed operation.
Upvotes: 2
Reputation: 58491
There is one more solution not yet mentioned:
Instead of returning the element itself, return its index. If there is no such element, either return -1 or the array size. This approach is quite common in C++ with iterators.
Upvotes: 2
Reputation: 13066
If the smallesNumberGreaterThanX
doesn't include x
itself then You can use something like this:
public int findSmallestNumberGreaterThanX(int a[], int x) {
// do what ever logic.
if (numFound) { return smallesNumberGreaterThanX; }
else {
return x;
}
}
And While you call the method it could be used like this:
int var = findSmallestNumberGreaterThanX(a ,x);
if (var == x)
{
System.out.println("No value found");
}
Upvotes: 2
Reputation: 462
I see several ways to solve this problem. I recommend using (1) or (2), and avoiding (3) and (4).
(1): throw an exception. Your method would look like:
public int findSmallestNumberGreaterThanX(int a[], int x)
throws NoSuchNumberException {
// do what ever logic.
if (numFound) { return smallestNumberGreaterThanX; }
else {
throw new NoSuchNumberException();
}
}
and would be called by saying
try {
int smallestNum = findSmallestNumberGreaterThanX(a, x);
//use smallestNum
} catch(NoSuchNumberException e) {
//handle case where there is no smallestNum
}
You would also have to create the class NoSuchNumberException:
public class NoSuchNumberException extends Exception {
public NoSuchNumberException() {}
public NoSuchNumberException(String message) {
super(message);
}
}
(2): Slightly refactor your code.
Instead of doing everything in one method, make the method
public int findSmallestNumber(int a[]) {...}
and then say
int smallestNum = findSmallestNumber(a);
if (smallestNum > x) {
//use smallestNum
} else {
//handle case where there is no smallestNum > x
}
(3): Set your return type to Integer, and return null.
Java will automatically cast between int and Integer, and null is a valid value for Integer. Just be sure to check for null wherever you use this method, because if you try to cast null to an int, it will break.
(4): return a number less than x. (I strongly recommend you do not use this solution unless you can also use that number somehow.)
Since the number is less than x, it can be identified as an error condition.
Upvotes: 3
Reputation: 19873
It depends on what your function returns. If it returns a value, then any value is valid so return value cannot be used for validity control.
If you return the index of the value you found in the array, then anything below zero can be considered as illegal value and can be used for error code.
Maybe you can add a parameter that will contain your return value, and change your function so that it will return a boolean indicating whether the number is found or not
Upvotes: 3
Reputation: 14715
If your comparison is strict you can return Integer.MIN_VALUE as it's the only value which cannot be returned in another way. (as it's smaller than all other values except itself).
Upvotes: 3