Yes I searched and found similar answers to similar questions, but not this question: Why?
Is there any real reason - performance, covariance or otherwise - for why Java Array's do 开发者_如何学Cnot have an indexOf methond?
Because it wasn't added to the the Arrays
class in the standard library and the JLS makes no provision for an indexOf
method for array objects.
This may be useful:
String[] someArray = ...;
List<String> l = Arrays.asList(someArray); // see comments
int index = l.indexOf("foo");
Happy coding.
If you look at it from the other side, why would they have an indexOf ?
indexOf can be an expensive operation as it would require equals() if the array were filled with Objects. An array is just not intended to be used that way and it shows in the API.
I do believe that it's good to have limited APIs which underscore the strengths of the implementation, and the strength of an Array is index-based access.
If you need fast searching for unique objects, use a Set.
There's nothing wrong in using arrays, but I think that choosing a class with the correct semantics will make the code more clear.
BTW in Arrays there happens to be a binarySearch, but it requires the array to be sorted (possibly in-place with Arrays.sort) so you can immediately grasp that the operation will be expensive.
The Java language engineers resist adding new methods to anything which is not in the class library.
Thus, arrays have only the .length
operator and the .clone()
method, nothing more.
Many useful methods for arrays were instead added to the class java.util.Arrays - but no indexOf
method.
For arrays of reference types (i.e. objects) you can use Arrays.asList(array).indexOf(object)
, but for primitive arrays there is no such List wrapper.
Of course, you can create such an indexOf
method yourself quite easily, just a lot of copy+paste to do it for all the primitive types.
public int indexOf(X[] array, X value) {
for(int i = 0; i < array.length; i++) {
if (array[i] == value) {
return i;
}
}
return NOT_FOUND;
}
(For the primitives, replace X
with the concrete value. For reference types use .equals(value)
instead == value
.)
Why is it not already done? Some speculation:
- This needs O(n) time (just like searching in lists), which is too slow for larger arrays. Better use some data structure which allows faster access.
- If you really need it, you either do something wrong, or can code it yourself in the object which "contains" your array.
My speculation:
1) prior to Java 5 (before primitive type auto-boxing exists) it's hard to decide when to use ==
and when to use equals()
since an array may contain primitive type or Object.
2) after Java 5, indexOf() is still not there probably because what Paŭlo Ebermann said.
In addition to what Paŭlo Ebermann said, I think the reason Java language engineers resisted is because they want the array to be like array in C++ and only want to integrated basic operations, such as length, as built-in array operations. IndexOf() is more of an utility operation so I think that's why it's not an built-in operation.
Something I am finding interesting here is how much depends on semantics: What does "array" mean in Java? I have always implicitly and for no good reason assumed that an "array" was a contiguous block of same-sized objects - I suspect mostly because that's how it gets implemented in a few other languages.
Clearly that's not the definition the Java designers used for "Array", though I don't know that anything would have been lost if they had.
In the cases where that is the definition, indexOf() is trivial and very, very fast.
Java arrays make the trade off of performance vs. functionality in favor of performance. One of the sacrifices made was the inability to have an indexOf method.
The List<E>
interface requires indexOf:
http://download.oracle.com/javase/1.5.0/docs/api/java/util/List.html
So instead of using a simple array, use one of:
- AbstractList
- AbstractSequentialList
- ArrayList
- AttributeList
- CopyOnWriteArrayList
- LinkedList
- RoleList
- RoleUnresolvedList
- Stack
- Vector
Probably it wasn't in the specs or was forgotten. Or, the makers were sending subliminal messages (use HashSets for a faster lookup, I dunno). Perhaps they wanted to eliminate redundancies in the libraries... One can only guess...
They didn't call it indexOf()
, they called it Arrays.binarySearch()
.
I would speculate that the developers decided that a general indexOf()
would be too slow, and easy enough for a developer to write if a linear time algorithm were suitable. Binary search on a sorted array is going to be faster than a plain linear search, except on pathological cases, and not as easy for a developer to get right first time.
精彩评论