Java如何优雅的通过表格中的规则计算结果
各位大神,下午好,请看问题描述:
Java程序需要根据下面表格中的规则计算得到物品编号:
红色 | 黑色 | ||||
高<10 | 20<高<50 | ... | ... | 高>1000 | |
宽<20 | FA | VF | ... | ... | QT |
20<=宽<30 | TA | MF | ... | ... | ZA |
30<=宽<80 | YN | VF | ... | ... | OP |
宽>=80 | UI | SR | ... | ... | OH |
注:表格中的...表示省略的更多规则
现在的写法:
Box box = boxService.getBoxById(10);String boxCode = "";
if(box.getWidth()<20){
if(box.getColor()=="红色"){
if(box.getHeight()<10){
boxCode = "FA";
}else if(box.getHieght() > 20 && box.getHieght() <50){
boxCode = "VF";
}
//省略...
}else if(box.getColor()=="黑色"){
//省略...
}
}else if(box.getWidth()>=20){
//省略...
}
上述写法需要大量的 if else ,而且如果条件过多,需要写很多代码, 请问有什么方法、工具可以优雅的处理这种问题吗?谢谢。
回答:
存在这样的二维表格,虽然不是很规整,但是说明稍加处理是可以查表的。
下面的代表中定义了两个辅助类:Column
和 Row
。核心代码在 getCode()
中。整个逻辑可以封装在一个工具类中,getCode 中取 row 和 column 的逻辑可以独立成函数,然后在 getCoe 中用 stream 和 optional 来组合逻辑。
package playground.sf.q1010000042100219;import java.util.List;
public class Solution {
private static List<Row> rows = initRows();
private static List<Column> columns = initColumns();
static String getCode(int width, int height, String color) {
var row = rows.stream()
.filter(it -> it.inRange(width))
.findFirst()
.orElse(null);
if (row == null) { return null; }
var column = columns.stream()
.filter(it -> it.getColor().equals(color) && it.inRange(height))
.findFirst()
.orElse(null);
if (column == null) { return null; }
return row.getCodes()[column.getIndex()];
}
public static void main(String[] args) {
System.out.println("Code: " + getCode(5, 5, "红色"));
System.out.println("Code: " + getCode(15, 25, "红色"));
System.out.println("Code: " + getCode(5, 1024, "黑色"));
System.out.println("Code: " + getCode(115, 115, "红色"));
}
private static List<Row> initRows() {
return List.of(
new Row(-1, 20, "FA", "VF", "QT"),
new Row(20, 30, "TA,MF,ZA".split(",")),
new Row(30, 80, "YN,VF,OP".split(",")),
new Row(80, -1, "UI,SR,OH".split(","))
);
}
private static List<Column> initColumns() {
int i = 0;
return List.of(
new Column(i++, "红色", -1, 10),
new Column(i++, "红色", 20, 50),
new Column(i++, "黑色", 1000, -1)
);
}
public static class Row {
private final int[] range;
private final String[] codes;
public Row(int min, int max, String... codes) {
range = new int[] { min, max };
this.codes = codes;
}
public int[] getRange() {
return range;
}
public String[] getCodes() {
return codes;
}
public boolean inRange(int value) {
return (range[0] < 0 || range[0] <= value)
&& (range[1] < 0 || range[1] > value);
}
}
public static class Column {
private final int index;
private final String color;
private final int[] range;
public Column(int index, String color, int min, int max) {
this.index = index;
this.color = color;
this.range = new int[] { min, max };
}
public boolean inRange(int value) {
return (range[0] < 0 || range[0] <= value)
&& (range[1] < 0 || range[1] > value);
}
public int getIndex() {
return index;
}
public String getColor() {
return color;
}
public int[] getRange() {
return range;
}
}
}
回答:
let goodsConfig = new Map([ [(color='',width=0,height=0)=>(color==='红色'&&width<20&&height<10),['FA','TA']],
[(color='',width=0,height=0)=>(color==='红色'&&width>=20&&height<10),['YN','UI']],
[(color='',width=0,height=0)=>(color==='红色'&&width<20&&20<height<50),['VF','MF']],
[(color='',width=0,height=0)=>(color==='红色'&&width>=20&&20<height<50),['UI','SR']],
]);
let getCode=(color='',width=0,height=0)=>{
let res=[];
for(let [fun,val] of goodsConfig.entries()){
if(fun(color,width,height)){
res = val;
break;
}
}
return res;
}
getCode('红色',10,30);
(2) ['VF', 'MF']
用js 实现了,参考@边城 的
https://segmentfault.com/a/11...
回答:
生成map,遍历表格,宽<20,红色,高<10 这三个数据md5一下,当做key,FA作为value
看错题目了,觉得把规则提出来比较好
public static void main(String[] args) throws ScriptException { String code = "if(color==='红色'&&width<20&&height<10) return 'NA'; else return 'FA';";
HashMap map = new HashMap();
map.put("color","红色");
map.put("width",10);
map.put("height",3);
System.out.println(eval(code,map));
}
static String eval(String code, HashMap<String,String> param_map) throws ScriptException {
code = "function f () {" + code + "} f()"; // Or otherwise
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("JavaScript");
param_map.entrySet().forEach(stringStringEntry -> {
engine.put(stringStringEntry.getKey(),stringStringEntry.getValue());
});
String result = (String)engine.eval(code);
return result;
}
回答:
策略模式应该能优雅的解决一下你的问题
回答:
规则引擎Drools
//规则一:所购图书总价在100元以下的没有优惠rule "book_discount_1"
when
$order:Order(originalPrice < 100)
then
$order.setRealPrice($order.getOriginalPrice());
print("所购图书总价在100元以下的没有优惠");
end
//规则二:所购图书总价在100到200元的优惠20元
rule "book_discount_2"
when
$order:Order(originalPrice < 200 && originalPrice >= 100)
then
$order.setRealPrice($order.getOriginalPrice() - 20);
print("所购图书总价在100到200元的优惠20元");
end
//规则三:所购图书总价在200到300元的优惠50元
rule "book_discount_3"
when
$order:Order(originalPrice <= 300 && originalPrice >= 200)
then
$order.setRealPrice($order.getOriginalPrice() - 50);
print("所购图书总价在200到300元的优惠50元");
end
//规则四:所购图书总价在300元以上的优惠100元
rule "book_discount_4"
when
$order:Order(originalPrice >= 300)
then
$order.setRealPrice($order.getOriginalPrice() - 100);
print("所购图书总价在300元以上的优惠100元");
end
function void print(String message){
System.out.printf("成功匹配到规则:%s",message);
}
回答:
有递进关系 宽 [10,20,30,..,100] 高 [10,20,30,..,100]
宽 for 宽; if i++ ; else break;
高 for 高; if j++ ; else break;res[i][j]
以上是 Java如何优雅的通过表格中的规则计算结果 的全部内容, 来源链接: utcz.com/p/944622.html