2

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 not have an indexOf methond?

Community
  • 1
  • 1
Andriy Drozdyuk
  • 58,435
  • 50
  • 171
  • 272
  • 1
    It seems as this question is not answerable. Unless one of the language designers happens to chime in, how will anyone know **why** this particular desired method was not included in the API? The reason for the omission is not in the JLS. Constructing your own indexOf method is simple to do (as linked post shows). – Atreys Aug 03 '11 at 21:28
  • The answer that there is not answer - IS an answer of itself. If you don't know the reason - that doesn't mean there is none. However, if there is no reason for the absence of it - then that is also an answer. – Andriy Drozdyuk Aug 04 '11 at 04:05
  • ^ Man, what was I drinking 5 years ago.... – Andriy Drozdyuk Nov 25 '16 at 04:21

9 Answers9

5

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.

3

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.

extraneon
  • 23,575
  • 2
  • 47
  • 51
  • "Because it's a handy method". Both Scala and .NET have *much* better integration of Arrays as "proper" collection types -- the implementation detail is just that, a detail. This is just one area where Java really shows how primitive it can be. –  Aug 03 '11 at 18:51
  • @pst, his answer to the question was that arrays were made for index-based access. So whether or not you agree with the decision to not include an indexOf() method for arrays, I highly doubt extraneon is in a position to change the java spec for you. You need to be complaining to someone else. :) And FYI, most people will agree with you that there are much better languages than java (Scala, C#, etc). – Jason Wheeler Aug 03 '11 at 19:08
  • @Bigwheels "Why *would* they have an indexOf?" was what my comment was related to. Using an array instead of an ArrayList or some other similar data-structure (assume a fixed size) with the same performance characteristics is an implementation detail (heck, Java could have even hid the "array syntax" if it felt like it). While perhaps not the best data-structure, it is silly to exclude such "abilities" from arrays -- and yes, I am well aware it *was* excluded. –  Aug 03 '11 at 19:11
  • @pst, There are probably plenty of handy methods which do not belong in a language-provided construct such as arrays. Instead of being actively "excluded", it may have just been not included. It definitely isn't necessary. – Atreys Aug 03 '11 at 21:11
  • @Atreys Compare to Arrays in .NET or Scala. There is no reason for this artificial divide -- much like the one imposed by primitives. It is the Java Way. However, this does not mean it is the Only Way or the Correct Way. –  Aug 03 '11 at 21:17
  • @pst I'll admit I am a newb at .NET and Scala; my comparison amongst (links follow:) [.NET](http://ideone.com/eKKpK), [Java](http://ideone.com/Lurot) and [Scala](http://ideone.com/Cm6Ys) using simple loops to sum up values seems illustrative of a difference between 'primitive' arrays in Java and Object based arrays of .NET and Scala. Admittedly my inexperience at the other two languages may have produced worse ways of summing up 10000 integers of an array 10000 times. – Atreys Aug 04 '11 at 01:03
  • I agree with you as I also think that this was done for performance reasons. Index of is an expensive operation, in an index-based data structure. – Andriy Drozdyuk Aug 04 '11 at 15:20
2

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.
rossum
  • 15,344
  • 1
  • 24
  • 38
Paŭlo Ebermann
  • 73,284
  • 20
  • 146
  • 210
1

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.

Alvin
  • 10,308
  • 8
  • 37
  • 49
1

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.

jimkberry
  • 1,317
  • 7
  • 8
  • Well, `O(n)` fast -- so why *not* include this (any many other "basic") operators upon array types? (There are many more available to the "real" collection types, like List.) –  Aug 03 '11 at 22:12
  • No, not O(n) fast. Constant time fast. I am assuming, of course, that the OP is talking about IndexOf() to find the position in the array of a reference to an *instance* of an object and not to an object with identical properties ( which would be more of a Find() ) Hmm. Looking at the other responses it seems most folks *are* talking about finding the index of a similar object in the array. That's not what I would have assumed an IndexOf() would be for. – jimkberry Aug 04 '11 at 14:40
  • Ooooh. My bad. I was NOT figuring that the Array collection needed to be implemented using Java. I was thinking that as part of the base library it could/would be native. Never mind. – jimkberry Aug 04 '11 at 14:56
0

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.

hspain
  • 17,528
  • 5
  • 19
  • 31
  • 2
    This is silly. Adding a method adds no run-time overhead to arrays. While the `indexOf` implementation itself would be the normal `O(n)` there is `Arrays.binarySearch` and `List.indexOf` so it's more arguable that Arrays are just poor forgotten children... –  Aug 03 '11 at 18:41
  • I don't get why this answer was upvoted. Twice. Adding this method to the library does not have degrade performance vs using asList and indexOf. Both are O(n). – Dhruv Gairola Aug 03 '11 at 18:51
0

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
Rag
  • 6,405
  • 2
  • 31
  • 38
0

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

Dhruv Gairola
  • 9,102
  • 5
  • 39
  • 43
0

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.

rossum
  • 15,344
  • 1
  • 24
  • 38
  • Binary searching requires that the input is sorted. Thus it is not the same. There is no reason why "index of would be too slow" (it is `O(n)`) -- certainly no slower than a standard array iteration. –  Aug 03 '11 at 22:10