0

Is it possible to search an array of objects in Java by a private attribute with the Array.binarySearch method? I was thinking there must be something similar to the sorting technique, where you create a class that implements Comparator and pass this in to Array.sort, but I can't seem to find anything (maybe there is something where instead of the compareTo method you just return the attribute used in the search)??

To be clear I have an array of anonymous Station objects, and this is passed to another class where I want to search the array for the name of the stations, which can be returned via a getName().

Any help would be much appreciated!

4 Answers4

5

Yes - in fact it uses Comparator, which you specified in your answer!

If you have a look over the implementations of the binarySearch method in the API, you come across binarySearch(T[] a, T key, Comparator c) which:

Searches the specified array for the specified object using the binary search algorithm.

You can implement the Comparator however you like, and so can use it to compare the private attributes alluded to in your question.

Edit responding to comment: The T is a generic parameter, meaning it can be anything, so long as it's the same in every position it appears. In this case, it means that the first parameter must be an array of the second parameter's type. Or in other words, if you're sorting an array of Ts (Stations in your case) then you need to pass in an instance of that class (Station here) to act as the object to compare against. This key argument will always be passed in as one of the arguments to the comparator's compare method.

So I suspect in your case you were passing in a String representing the station name; you should instead pass in an instance of Station which has the appropriate name.

Community
  • 1
  • 1
Andrzej Doyle
  • 102,507
  • 33
  • 189
  • 228
  • Hey thanks for you answers, I did look into this but was confused... I passed in the array, a string and the comparator I used for the sort I mentioned, but get this error: The method binarySearch(T[], T, Comparator super T>) in the type Arrays is not applicable for the arguments (Station[], String, StationCompare) Also I'm obviously missing something if I'm just using the same comparator, but 'comparator' only has two methods, compare and equals, so not sure what to do. I'm new to java - I guess the T is just a parent object? Sorry, there's lots of questions there... –  Jul 19 '10 at 15:07
  • Thanks for you help and clearing this up for me, much appreciated! –  Jul 19 '10 at 16:12
2

Yes, there's an overload that takes a comparator. Remember that you can only use binarySearch if the array is already sorted.

Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
0

If the array of stations is not already sorted by the station names, it makes no sense sorting and searching for every query. It is faster to do a linear search in this case. However, if you can sort the array and then perform multiple binary searches, it is worthwhile. Implement a comparator such as the following, and use it for both sorting (Arrays.sort(..)) and searching (Arrays.binarySearch(..)):

private class StationNameComparator implements Comparator<Station> {
    public int compare(Station s1, Station s2) {
        return s1.getName().compareTo(s2.getName());
    }
}

Note that I assume that the names are non-null and unique.

Eyal Schneider
  • 22,166
  • 5
  • 47
  • 78
  • Hi, Thanks, please see my comments on one of the answers above, and yes they are already sorted (this was required for another purpose). I did pass this comparator in which worked for the sort, but there's an error with the search... probably something fundamental... –  Jul 19 '10 at 15:11
  • @Pickles: you passed wrong arguments. The search method expects the array, the item, and then the comparator. The item must be of type Station, since this is the type of the array's items. Therefore, you must use a dummy station object with the required name every time you search. – Eyal Schneider Jul 19 '10 at 15:55
  • hey thanks for you help, that's what I eventually did but thought it was the wrong way to do it, probably should have refreshed this page a few minutes ago! –  Jul 19 '10 at 16:07
0

Thanks, eventually got it working using

Arrays.binarySearch(allStations,new Station("nameofstationhere"),new StationCompare())

which is probably a bad way as I'm creating a new Station object for comparison... but it works and not sure how to do it using just the string...

  • If creating many instances bothers you, you can use the same instance of the comparator for all searches (since it is stateless). Also, Assuming that all searches run in the same thread, you can reuse the same temporary Station object, and change its name field before searches. Anyway, I wouldn't be concerned about excessive object creation, unless it proves to be the source of some performance problem. – Eyal Schneider Jul 19 '10 at 16:45
  • Yeah good point... it's not really the object creation that's annoys me, I was just thinking it was a bit strange that you have to create an object this way (for example with a larger object you may have to pass in a number of null parameters and what if the creation of an object caused some other unwanted behaviour). It would be nice if you could just pass in any type of object to the search method and overload the comparator as required, but hey, it beats doing everything manually so I'm not complaining! Thanks again for your comments. –  Jul 19 '10 at 17:22