3

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 ?

  1. Effective java mentions return empty array instead of null pointer - but is it worth creating an array if function returns single element ?

  2. Next option is return null. I have seen bunch of posts which reject the idea of returning null.

  3. Third is to return an object { boolean found; int value; } . This sounds like an overkill.

Please suggest me a best approach here.

Ali
  • 56,466
  • 29
  • 168
  • 265
JavaDeveloper
  • 5,320
  • 16
  • 79
  • 132
  • possible duplicate of [Avoiding "!= null" statements in Java?](http://stackoverflow.com/questions/271526/avoiding-null-statements-in-java) – Elazar Jun 22 '13 at 23:38
  • I have stated all options explored on other questions on stack overflow. There appears to mixed answers- none directly addressing this particular scenario - apologies but could not reach any conclusion. – JavaDeveloper Jun 22 '13 at 23:41
  • 1
    Will `smallesNumberGreaterThanX` include `x` in any condition? – Vishal K Jun 23 '13 at 00:01

7 Answers7

3

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).

sasha.sochka
  • 14,395
  • 10
  • 44
  • 68
3

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

Eric
  • 19,525
  • 19
  • 84
  • 147
3

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.

Martin Wickham
  • 442
  • 4
  • 9
  • Thanks - but which one of the options is Most recommended.. in a generic case were an element 'which could be a single object, a float, anything which is not a collection' needs to be returned ? I – JavaDeveloper Jun 23 '13 at 00:06
  • Sometimes there is no standard method, from a structural point of view I like the exception most (no special perpose magic numbers) but exceptions are very expensive so in practice I usually use w -1 or null (depending on if returning an primative or an object) – Richard Tingle Jun 23 '13 at 09:23
  • @JavaDeveloper I would say either (1) or (2) would be recommended. There is not necessarily a 'right answer' when structuring a program. But if you're designing a generic method that can return anything, you may want to reconsider that. The output would be unusable unless you know exactly what it is (or unless you use lots of instanceof statements, but that's generally looked down upon.) Although if you really want to you could just return Object. – Martin Wickham Jun 23 '13 at 17:26
2

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");
}
Vishal K
  • 12,976
  • 2
  • 27
  • 38
2

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.

Ali
  • 56,466
  • 29
  • 168
  • 265
2

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.

Petr
  • 62,528
  • 13
  • 153
  • 317
  • Sounds good..but how is it much different than option 3 'Third is to return an object { boolean found; int value; } . This sounds like an overkill.' Instead of interface and 2 classes I would just return a single class ? – JavaDeveloper Jun 23 '13 at 18:57
  • @JavaDeveloper It is similar, you could implement `Option` internally as you suggest. This variant is polymorphic, so you can use it for any purpose. It's not overkill at all - the implementation details aren't that important, what matters at the end is code clarity. If you avoid `null`s and use `Option<...>` instead, it will be always clear what values are optional and what values are required. [Here](http://danielwestheide.com/blog/2012/12/19/the-neophytes-guide-to-scala-part-5-the-option-type.html) is a nice tutorial to Scala's `Option`. – Petr Jun 24 '13 at 06:42
0

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:

  1. Throw an Exception if not found
  2. Change the return type to an object type and return null

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;
}
Bohemian
  • 412,405
  • 93
  • 575
  • 722