Java如何优雅的通过表格中的规则计算结果

各位大神,下午好,请看问题描述:

Java程序需要根据下面表格中的规则计算得到物品编号:

红色黑色
高<1020<高<50......高>1000
宽<20FAVF......QT
20<=宽<30TAMF......ZA
30<=宽<80YNVF......OP
宽>=80UISR......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 ,而且如果条件过多,需要写很多代码, 请问有什么方法、工具可以优雅的处理这种问题吗?谢谢。


回答:

存在这样的二维表格,虽然不是很规整,但是说明稍加处理是可以查表的。

下面的代表中定义了两个辅助类:ColumnRow。核心代码在 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

回到顶部