Reputation: 303
Given the following TreeMap
:
Map<Double, Integer> treeMap = new TreeMap<Double, Integer>() {{.
put("52.1", 1);
put("53.4", 2);
put("57.1", 3);
put("59.4", 7);
put("60.2", 11);
put("71.6", 16)}};
What would be the best way to return the closest n matches (in both directions) for a given double? For instance, n=2 and "58.0" would return 53.4, 57.1, 59.4, 60.2
Upvotes: 1
Views: 687
Reputation: 338730
new TreeMap <>(
Map.of(
52.1d , 1 ,
53.4d , 2 ,
57.1d , 3 ,
59.4d , 7 ,
60.2d , 11 ,
71.6d , 16
)
)
.floorKey( 58.0d ) // Or call `.ceilingKey( 58.0d )`
See this code run live at IdeOne.com.
57.1
NavigableMap::lowerKey/higherKey
TreeMap
is a NavigableMap
.
The NavigableMap
interface provides methods for retrieving adjacent keys (and entries).
Repeat the commands to fetch as many adjacent keys as you desire, until receiving a null
.
On second reading, it seems you do not have a key. You have a value you want to compare to keys in a map.
In this case, fetch a Set
of all the keys in the map. NavigableMap
extends SortedMap
. So we can call SortedMap::keySet
. The returned set iterates in sorted order.
Set< Double > set = map.keySet() ;
Make a List
of that, to access individual elements by index.
List< Double > doublesListSorted = List.of( set.toArray() ) ; // Get un-modifiable list.
Now you can loop the sorted list to compare values.
NavigableMap::floorKey/ceilingKey
Or, as dnault commented, we can ask the NavigableMap
to compare key values for a nearest-match.
floorKey
ceilingKey
Make an input map. We use Map.of
initially for its convenient literal syntax. Then we feed that un-modifiable map to the constructor of TreeMap
. Our literal input seen here happens to be sorted, but that is irrelevant, as the TreeMap
constructor will sort the entries by key.
NavigableMap < Double, Integer > map =
new TreeMap <>(
Map.of(
52.1d , 1 ,
53.4d , 2 ,
57.1d , 3 ,
59.4d , 7 ,
60.2d , 11 ,
71.6d , 16
)
);
map.toString(): {52.1=1, 53.4=2, 57.1=3, 59.4=7, 60.2=11, 71.6=16}
Set our target to which we want the closest matches.
Double target = 58.0d;
Get the adjacent keys, next lower, and next higher.
Double nextLower = map.floorKey( target );
Double nextHigher = map.ceilingKey( target );
nextLower = 57.1 nextHigher = 59.4
See this code run live at IdeOne.com.
Notes:
List.of
literal syntax shown in this Answer.BigDecimal
rather than Double
.Upvotes: 3