I have a map of <String,Double>
considered as thresholds to classify a list of Doubles
HashMap<String, Double> map = new Hashmap<>();
map.put(A/B,0.7);
map.put(B/C,0.4);
map.put(C/D,0.3);
map.put(D/E,0.1);
The Doubles of the hash is used as threshold to classify a list doubles given, so I want to transform this map into a list of classes A, B, C, D
Class A : from 0.7
Class B : from 0.4 to 0.7
Class C : from 0.3 to 0.4
Class D : from 0.1 to 0.3
Class E : less than 0.1
Do you have any idea on how to perform that as a method StringClassifyByValue(HashMap<String, Double> map, Double value){}
returning a String of the class correspondent of the value given as parameter?
ِExample :
this.StringClassifyByValue(map,0.5)
have to return B.
Some thoughts: first of all, your data structure is not really helping with the problem you want to solve. But that is exactly what data structures exist for: to give you a helpful abstraction that allows you to efficiently solve your "most important" problem.
Coming from there, I would suggest that you start by creating classes that better fit your problem statement. You could start with something like
public class Interval {
private final double lowerBoundary;
private final double upperBoundary;
public Interval(double lowerBoundary, upperBoundary) {
this.lowerBoundary = ...
}
public boolean contains(double value) {
return (value >= lowerBoundary) && (value <=upperBoundary);
}
And instead of keeping of using a Map<String, Double>
you rather have something like List<Pair<Classification, Interval>>
where:
Pair
could be a class that simply holds two values that belong together (instead of using a "generic" pair class, you could also create your own custom class that combines a Classification
with an Interval
).Classification
represents a "class", like A, B, C, in your example. The point is: be careful about using raw String objects for such purposes. Maybe a simple string is fine for now, but maybe you have to further enhance your logic later on - to then find that "hm, now a simple string doesn't do any more, but now I have to update a ton of places to change that".And of course: ideally, you would sort the above list by "intervals". Then finding the Classification
for a specific double value is super simple:
for (Pair<Classification, Interval> combo : listOfPairs) {
if (combo.getInterval().contains(value)) {
return combo.getClassification(); // yeeha found one
}
}
return "nothing found" ... or throw some kind of exception
Long story short: I can't tell you how to best transform your existing map into the above list of pair objects - because I don't know the big picture. It might be possible to simply not create that map initially, and directly build such a list of objects.
And for the record: if that map exists as map because there are other, more important requirements ... then you have to carefully balance if you really want to keep using map+list (means "double book-keeping") or if you put all of the above logic into some service that turns your Map into a List, does the lookup and then throws away this "other" representation of your data.