Reputation: 24527
I need some advice in terms of performance. I've got a Map<DateTime, String>
. And I need something like the following method:
Map<DateTime, BigDecimal> map; // about 50 entries. Btw: Which impl to choose?
BigDecimal findNextSmaller(DateTime input) {
DateTime tmp = null;
for(DateTime d : map.keySet()) {
if(tmp == null && d < input) {
tmp = d;
}
if(d < input && d > tmp) {
tmp = d;
}
}
return map.get(tmp);
}
So basically I just iterate over the keySet of my Map
and try to find the key which is the next smallest compared to input
.
This method will get called about 1.000.000 times in a row:
BigDecimal sum;
List<Item> items; // about 1.000.000 Items
for(Item i : items) {
sum = sum.add(findNextSmaller(i.getDateTime()));
}
Now I'm looking for a way to make things faster.
My first thought was to make an OrderedList
out of the Map
's keySet. So in average I just have to iterate over half of the DateTime
s. And then just do a map.get(dateTimeFromOrderedList)
to get the matching value.
But is that all I can do about it?
Upvotes: 0
Views: 85
Reputation: 3589
Have a look at NavigableMap. This seems to be exactly what you need.
As you are searching for the DateTime closest and strictly less than the input, I would choose floorEntry(key) for the lookup. But make sure that you are handling nulls correctly. There may not be a key in the map that is strictly smaller than the input! If you try to add a null reference to a BigDecimal, a NullPointerException will be thrown.
Upvotes: 3
Reputation: 328608
You can use a TreeMap which has a built-in method for that:
TreeMap<DateTime, BigDecimal> map = new TreeMap<>();
//populate the map
BigDecimal findNextSmaller(DateTime input) {
return map.ceilingEntry(input).getValue(); //add exception checking as required
}
Note: you may want ceilingEntry
or higherEntry
depending on whether you want (resp.) >=
or >
.
Upvotes: 4