假设我希望我的应用程序根据某些标准确定用户的健康水平。
标准可能是这样的:年龄,正在服用药物?,400米跑
起初我虽然可以创建一个Map,其中值是适应度级别,而键是一个具有所有条件的对象,但由于条件是范围,因此不起作用。
例如: 如果年龄在18到22之间且onMedication = false且run400m = [70,80]
健康水平=好
现在,如果只有一个参数在不同的范围内,则适应度水平会有所不同。我怎么能做到这一点?
答案 0 :(得分:1)
您可以使用TreeMap类。有非常有用的方法来处理键值范围。例如:
TreeMap<Integer, String> myTreeMap = new TreeMap<>();
myTreeMap.put(10, "A");
myTreeMap.put(20, "B");
myTreeMap.put(30, "C");
myTreeMap.put(40, "D");
System.out.println(myTreeMap.floorEntry(25));
将打印第二个选项(20 = B)。我建议您检查TreeMap及其所有方法。
答案 1 :(得分:1)
也许您可以使用OOP并执行以下操作:
public class FitnessApp {
public static void main(String[] args) {
Map<String, Object> params = new HashMap<>();
params.put("age", 17);
params.put("onMedication", false);
System.out.printf(new FitnessLevelCalculator().calculateFor(params).name());
}
}
class FitnessLevelCalculator {
private LinkedList<FitnessLevel> fitnessLevels = new LinkedList<>();
public FitnessLevelCalculator() {
fitnessLevels.add(new FitnessLevel(FitnessLevelEnum.ATHLETIC, Arrays.asList(new RangeCriteria("age", 18, 25), new BooleanCriteria("onMedication", false))));
fitnessLevels.add(new FitnessLevel(FitnessLevelEnum.GOOD, Arrays.asList(new RangeCriteria("age", 14, 17), new BooleanCriteria("onMedication", false))));
fitnessLevels.add(new FitnessLevel(FitnessLevelEnum.ILL, Arrays.asList(new RangeCriteria("age", 16, 17))));
}
public FitnessLevelEnum calculateFor(Map<String, Object> params) {
ListIterator<FitnessLevel> listIterator = fitnessLevels.listIterator();
while (listIterator.hasNext()) {
FitnessLevel fitnessLevel = listIterator.next();
if (fitnessLevel.accept(params)) {
return fitnessLevel.getLevel();
}
}
return FitnessLevelEnum.NOT_CLASSIFIED;
}
}
enum FitnessLevelEnum {
ILL, GOOD, ATHLETIC, NOT_CLASSIFIED
}
class FitnessLevel {
private List<Criteria> criteriaList = new ArrayList<>();
private FitnessLevelEnum level;
public FitnessLevel(FitnessLevelEnum level, List<Criteria> criteriaList) {
this.criteriaList = criteriaList;
this.level = level;
}
public boolean accept(Map<String, Object> params) {
for (Criteria criteria : criteriaList) {
if (!params.containsKey(criteria.getName())) {
return false;
}
if (!criteria.satisfies(params.get(criteria.getName()))) {
return false;
}
}
return true;
}
public FitnessLevelEnum getLevel() {
return level;
}
}
abstract class Criteria<T> {
private String name;
public Criteria(String name) {
this.name = name;
}
public abstract boolean satisfies(T param);
public String getName() {
return name;
}
}
class RangeCriteria extends Criteria<Integer> {
private int min;
private int max;
public RangeCriteria(String name, int min, int max) {
super(name);
this.min = min;
this.max = max;
}
@Override
public boolean satisfies(Integer param) {
return param >= min && param <= max;
}
}
class BooleanCriteria extends Criteria<Boolean> {
private Boolean expectedValue;
public BooleanCriteria(String name, Boolean expectedValue) {
super(name);
this.expectedValue = expectedValue;
}
@Override
public boolean satisfies(Boolean param) {
return param == expectedValue;
}
}
答案 2 :(得分:0)
在您的具体情况下,我认为在Map中使用键是不好的。可能有一种方法可以将具有所有条件的Object作为您的业务,但它非常复杂且不值得这样做。 Interpreter Pattern
可能对此有所帮助。
希望得到这个帮助。