Yes, using the list the way you've described (that is, sorting it by using the given comparator and then using binary search with the same comparator) is possible, and it is reasonable to implement it for learning purposes. It is only inefficient. Since sorting is quite expensive, you'd have always better response if you simply iterated through the unsorted list and returned first record which would match given value using the comparator.
Jo Jake wrote:But, still I was wondering how to send String searchKeyword as second argument to binarySearch method when it expects movie object ? I think that is not practically doable right ? Probably binarySearch could be preferred only if I have ArrayList of Strings and then I have a searchKeyword string ??
Well, it is doable, and in more than one way:
1) Your current code seems to be creating a new instance of
Movie and only filling in the movie name, and using this instance in the binary search. You might create the instance in the
searchByMovieName method, therefore hiding its existence from the outside world. This is fraught with problems, however. If the
Movie class has many attributes, you would have to leave the others uninitialized or even provide some bogus values of them. And if such a
Movie instance slipped outside of the place it was intended to be used, it could cause errors and exceptions in methods which expect all of the attributes to contain some meaningful value. So while this is doable, it is not a good thing to do.
2) You could create a comparator which would be able to compare a
String to a
Movie. The comparator is not obliged to only compare objects of the same class. You could inspect the class of the objects passed to the comaprator (probably using the
instanceof operator) and if one of them was
String and the other
Movie, you could compare the movie name to the value of the string. Such comparator could be then used to binary search a movie by name given in a String.
Of course, there are downsides. Firstly, such comparator cannot be cleanly declared using generics. There is no way to express that a comparator can accept
Movie instances
or String instances, so you'd have to declare it as a comparator over the common parent of these two classes, which is
Object. Therefore we lose type safety. This indicates the design is problematic from the OOP point of view.
Secondly, this construct is very unusual and it would give headaches to anyone who would happen to deal with your code (including yourself a year from now), since he (you) would struggle to understand what's going on. Even if it was well documented, it is still something which is not usual and it would be easy to make a mistake or overlook an undesired side effect of this solution. You should strive to write code that is maintainable in the long run; code which advertises "I'm clever" usually fails the former criterion.
I'm describing this only to help you understand that the
binarySearch methods don't care what the comparator does and what types it operates on. As long as it provides a well-defined order over all objects that will be feed to the comparator, it can be successfully used in the binary search. And we can actually improve the idea a bit:
3) Create an interface called eg.
MovieNameProvider with a single method
String getMovieName(). Have
Movie implement this interface (easy, huh?). Create a comparator declared as
MovieNameComparator implements Comparator<MovieNameProvider> which will compare instances according to the movie name. Now, when doing a binary search, we can do this:
(Note we had to declare the
movieName parameter as
final; this is useful trick to learn when using anonymous or local classes.)
You would create similar interfaces and comparators for other attributes of the Movie class which you want to sort/search by. And you'd have a code which does practically the same thing as the first case I've described, but it is type safe and employs interfaces and comparators whose purpose is simple, clear and focused.
Jo Jake wrote:Regarding filters that you mentioned, you mean to make a custom filter function isn't (Or is there any Core Java Classes supporting filtering this kind ) ? The custom filter function is supposed to search through the list of objects through a for loop and finds all objects that contains the searched value in each object's field values right ?.
No, the Collections framework does not have built-in support for this kind of filtering. But it is quite easy to write your own generic classes and methods to this end. For example, I've created a simple interface:
and then wrote methods which allow me to copy only items matched by a filter from one collection to another, or create a filtered iterator which takes another iterator and a filter and skips over items not matched by given filter.
I'm pretty sure there are third party libraries there which provide functionality similar to this filtering (or otherwise suitable to your needs), such as the
Google Guava libraries. You might try to have a look at them after you learn the Java's own Collections framework.