I need to find the most effecient way to find a random element from the most popular category
From
4 Cheese
1 Olive
2 Mushroom
4 Ham
2 Chicken
4 Salad
I want either Cheese
or Ham
or Salad
. If there are multiple top categories I don't care which category I will get my item from.
On the input I have Iterator<Foo>
where Foo
implements
Interface Foo {
int getCategory();
}
My current code looks like this:
Foo getItem(Iterator<Foo> it) {
Map<Integer, List<Foo>> categoryMap = new HashMap<Integer, List<Foo>>();
while(it.hasNext()) {
Foo foo = it.next();
int category = foo.getCategory();
List<Foo> l = categoryMap.get(category);
if(l == null) {
l = new ArrayList<Foo>();
categoryMap.put(category, l);
}
l.add(foo);
}
int longest_list_size = 0;
int longest_category_id = -1;
Set<Integer> categories = categoryMap.keySet()
for(Integer c: categories ) {
int list_size = categoryMap.get(c).size();
if(list_size > longest_list_size) {
longest_list_size = list_size;
longest_category_id = c;
}
}
if(longest_list_size == 0)
return null;
int r = new Random().nextInt(longest_list_size);
return categoryMap.get(c).get(r);
}
Probably faster to have 2 maps:
You could do further optimization in many places, but you get the idea.