views:

2595

answers:

5

Suppose you have a collection of a few hundred in-memory objects and you need to query this List to return objects matching some SQL or Criteria like query. For example, you might have a List of Car objects and you want to return all cars made during the 1960s, with a license plate that starts with AZ, ordered by the name of the car model.

I know about JoSQL, has anyone used this, or have any experience with other/homegrown solutions?

+1  A: 

I would use a Comparator that takes a range of years and license plate pattern as input parameters. Then just iterate through your collection and copy the objects that match. You'd likely end up making a whole package of custom Comparators with this approach.

Bill the Lizard
Simplicity. Who would have thunk!?
Allain Lalonde
Could you elaborate please? I understand how to create a custom Comparator and implement the compare method to compare on some property. But I'm not sure how to accomplish this with multiple input parameters?
stian
+1  A: 

If you need a single concrete match, you can have the class implement Comparator, then create a standalone object with all the hashed fields included and use it to return the index of the match. When you want to find more than one (potentially) object in the collection, you'll have to turn to a library like JoSQL (which has worked well in the trivial cases I've used it for).

In general, I tend to embed Derby into even my small applications, use Hibernate annotations to define my model classes and let Hibernate deal with caching schemes to keep everything fast.

Steve Moyer
Embedding an in-memory database like Derby sounds like a good idea, particulary since Derby is now a part of the JDK. Introducing Hibernate to the mix would be a bit overkill for my use. I'd just go with SQL/JDBC i guess.
stian
+3  A: 

I have used Apache Commons JXPath in a production application. It allows you to apply XPath expressions to graphs of objects in Java.

Eric Weilnau
A: 

The Comparator option is not bad, especially if you use anonymous classes (so as not to create redundant classes in the project), but eventually when you look at the flow of comparisons, it's pretty much just like looping over the entire collection yourself, specifying exactly the conditions for matching items:

if (Car car : cars) {
 if (1959 < car.getYear() && 1970 > car.getYear() &&
   car.getLicense().startsWith("AZ")) {
  result.add(car);
 }
}

Then there's the sorting... that might be a pain in the backside, but luckily there's class Collections and its sort methods, one of which receives a Comparator...

Yuval
This is the approach I am using now and it quickly gets unwieldly when the criterias increases. But it's probably okay for the simple example.
stian
+2  A: 

Continuing the Comparator theme, you may also want to take a look at the Google Collections API. In particular, they have an interface called Predicate, which serves a similar role to Comparator, in that it is a simple interface that can be used by a filtering method, like Sets.filter). They include a whole bunch of composite predicate implementations, to do ANDs, ORs, etc.

Depending on the size of your data set, it may make more sense to use this approach than a SQL or external relational database approach.

joev
I'll definitely have a look at that library! Thanks!
stian