我有一组对象。该对象根据请求参数计算一些数字。我们称它们为计算器。每个计算器都有说明,其中指定了该计算器最适合的请求类型。 例如,
Calculator1 : with this parameters : price > 10, gender = male, geo_id = 1, 2 or 3.
Calculator2 : with this parameters : price < 5, gender = male, geo_id = 1, 2.
请求:price = 11, gender = male, geo_id = 2
我应该得到最合适的 calculator1,然后是 calculator2。
对于请求:price = 4, gender = male, geo_id = 2
我应该得到 calculator2,然后是 calculator1。
对于请求:price = 3, gender = female, geo_id = 5
我应该只得到第二个。
现在我正在用 Lucene 做这件事,但它并不真正适合这项任务。你能给我推荐一些库或方法吗?
最佳答案
我的建议是使用比较器。请参阅下面的类的草图。
import java.util.HashMap;
import java.util.Map;
public abstract class Calculator {
public static Map<String, Integer> weights;
static {
weights = new HashMap<String, Integer>();
weights.put("price", 10);
weights.put("gender", 2);
weights.put("geo", 5);
}
public abstract int calculate(Map<String, Integer> request);
public abstract int fitnessFor(Map<String, Integer> request);
}
您可以使用权重来调整各个请求参数的相对重要性。
import java.util.Map;
public class Calculator1 extends Calculator {
public int calculate(Map<String, Integer> request) {
return -1;
}
@Override
public int fitnessFor(Map<String, Integer> request) {
int fitness = -1;
Integer price = request.get("price");
if (price == null)
return fitness;
if (price > 10)
fitness += weights.get("price");
return fitness;
}
public String toString() { return "Calculator1"; }
}
Calculator1 只关心昂贵的项目。
import java.util.Map;
public class Calculator2 extends Calculator {
public int calculate(Map<String, Integer> request) {
return -1;
}
@Override
public int fitnessFor(Map<String, Integer> request) {
int fitness = -1;
Integer price = request.get("price");
if (price == null)
return fitness;
if (price < 5)
fitness += weights.get("price");
Integer gender = request.get("gender");
if (gender == null)
return fitness;
if (gender == 1)
fitness += weights.get("gender");
return fitness;
}
public String toString() { return "Calculator2"; }
}
Calculator2 关心价格较低的项目,尤其是。如果他们是性别 1。
比较器只是比较计算器相对于请求的适应度:
import java.util.Comparator;
import java.util.Map;
public class CalcComparator implements Comparator<Calculator> {
private Map<String, Integer> request;
public CalcComparator(Map<String, Integer> request) {
this.request = request;
}
@Override
public int compare(Calculator c1, Calculator c2) {
int c1Fitness = c1.fitnessFor(request);
int c2Fitness = c2.fitnessFor(request);
if (c1Fitness == c2Fitness)
return 0;
if (c1Fitness < c2Fitness)
return 1;
return -1;
}
}
尝试一下:
public class Main {
public static void main(String[] args) {
Map<String, Integer> request = new HashMap<String, Integer>();
request.put("price", 5);
request.put("gender", 1);
List<Calculator> calculators = new ArrayList<Calculator>();
calculators.add(new Calculator1());
calculators.add(new Calculator2());
Collections.sort(calculators, new CalcComparator(request));
System.out.println("For request: "+request);
for (Calculator c : calculators) {
System.out.println("\t"+c.toString() + "( fitness " + c.fitnessFor(request) + ")");
}
}
}
这只是一个草图来说明这个想法。您可能想要为请求参数引入一个枚举,可能引入一个 Request 类,很可能完全改变适应度的计算方式,将一些字段设为私有(private)并封装它们等。
优点是您可以轻松地根据计算器对请求的适用性对所有计算器进行排序。
关于java - 通过java中的参数集找到最合适的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21277865/