I'm reading the source code of Java Collections Framework and noticed the List#indexOf
method. In the documentation for this method, it said
Returns the index of the first occurrence of the specified element in this list, or -1 if this list does not contain the element.
I'm curious why it should return -1 precisely... Just returning a negative number is enough to meet the requirements, here are my points of view:
Compare whether a number is negative is easier than comparing whether a number is -1
You're thinking about it from the wrong 'side'. Consider Postel's Law, which roughly states:
Be liberal in what you accept, and conservative in what you send.
And apply it to API design.
You're free to write:
if (list.indexOf(something) < 0) ....
Which works, every time, because -1
is a negative number.
What possible point is there in writing the API to be 'any negative number' instead?
Let's go through it:
It documentarily suggests that users of the API ought to write < 0
instead of != -1
- but this is not much of an argument: At best you can then say that the docs can say that whilst -1 is always returned, users of the API ought to use < 0
to check. Except this is ridiculous: The proper way to check is not to call indexOf
at all and to call .contains()
instead.
It makes it easier to write code that calls .indexOf
. This is false - you can write < 0
just the same. In places where you need the index to be stable, which can occur (imagine you are storing some data in a java.util.Map<Integer, X>
collection, and your procedure is to look up some key in a list to figure out the id (an integer), and then map that, and you have the need to map 'key not found' to something too. If .indexOf()
was specced to return any negative number to indicate not found, you'd have to 'clean' this data to -1, but you don't have to, it's guaranteed to be -1.
It makes it easier to write implementations of java.util.List
. This seems like a frivolous argument (how often are you implement j.u.List? Not exactly a daily occurrence, unlike calling it). I rather doubt it'll actually result in shorter code, and I really doubt that code would be more readable.
So, what possible point is there?
Remember, it's an API spec. Not every decision needs an explanation beyond 'we needed something specific, as the purpose of an API is to decree the common ruleset. Sometimes just picking anything is the main win, and it doesn't much matter which of many identical choices is picked. As long as everybody is in agreement to use the same pick, it's fine'. That explains why it is -1 and not, say, -100, or Integer.MIN_VALUE
(-2^31). They could have picked that. They didn't. -1 is marginally simpler (writing -1
is simpler than Integer.MIN_VALUE, it is the 'first' negative value, and it somewhat matched established convention such as e.g. various C libraries that return -1 to indicate not found.