Yeah let's see, to boil it down: either way there has to be a way to signal the user isn't known, and either way the caller has to handle it. I've always preferred exceptions to null, all else being equal. I don't mind the idea of exceptions being used for control flow; they aren't that expensive. (In a performance-critical block, OK, I'd use null instead, but here, this case is rare enough that I don't think performance is a factor.)
Catching an exception needs a bit more code than handling null. You can't force a caller to handle null, but you can force a caller to handle an exception -- but here I'm using an unchecked exception so that doesn't matter anyway. You have a point about catching this maybe masking another exception. I could be talked into changing this, but here, I think the right behavior for a DataModel is to know about all users that exist, not just ones with preferences. That is this user should be known in your situation. But are you using FileDataModel or something similar? because this condition isn't really fulfilled by this implementation. It only knows about users that have expressed a preference, by its nature. That can be addressed so that you can express users, without expressing a preference. If this is the issue -- let me attack that issue directly to solve this, and punt on the exception vs. null discussion. Am I right? Sean On 21 Jan 2009, 3:23 PM, "Otis Gospodnetic" <otis_gospodne...@yahoo.com> wrote: Hello, Question about NoSuchElementException usage in Taste: I'm using Taste in an environment where lots of requests for recommended items are for users who are new to the system - users who have no previously consumed items. When I try to get recommendations for such users, the following is thrown: java.util.NoSuchElementException at org.apache.mahout.cf.taste.impl.model.BooleanUserGenericDataModel.getUser(BooleanUserGenericDataModel.java:81) at org.apache.mahout.cf.taste.impl.model.file.BooleanPrefUserFileDataModel.getUser(BooleanPrefUserFileDataModel.java:163) at org.apache.mahout.cf.taste.impl.recommender.BooleanUserGenericUserBasedRecommender.recommend(BooleanUserGenericUserBasedRecommender.java:86) This looks correct, and comes from this piece of code in BooleanUserGenericDataModel (the same happens in non-Boolean versions of the code): public User getUser(Object id) { User user = userMap.get(id); if (user == null) { throw new NoSuchElementException(); } return user; } I'm wondering if this is good/best thing to do here. Here is some reasoning: - it's not really an error to ask a RE to recommend items for a user the RE knows nothing about - it's the cold start issue - I believe throwing exceptions is expensive, and I'm wondering if it would be cheaper to do something else - one could say this falls in the "using exceptions for flow control" category (because that's what I'll have to do on the higher level) - I briefly looked at returning null, but it looks like this would require checks for null to avoid NPE in a number of places I'm not sure this needs to change, but it's been on my mind for a while now. On my end I can simply catch this ugly exception and eat it, although this "NoSuchElementException" is so non-specific that if I just catch NoSuchElementException the code may one day end up catching a NoSuchElementException from some other part of Taste. Thoughts? Otis -- Sematext -- http://sematext.com/ -- Lucene - Solr - Nutch