Best approach to implement a static table like structure in Java

Viewed 253

I need to create a simple table with possibly 13 input columns and 1 output column. The data inside this table won't change. enter image description here

Similar to what we see in this diagram/picture. I am trying to find the best approach.

  1. Use a .dmn table (decision table)

PROS - Decision table is a static table and can help implement this logic easily.

CONS - In my OSGi microservice, I have never used a jBpmn or Camunda or any such bpmn library. So it is an overhead to import , learn and use a library just to create a decision table. Do you agree?

  1. Create a data structure in java itself that will hold this static table. However, the big question is how to create such a data structure in java?

    One way but not-so-clean way is to use a map with key as the concatenation of all the input columns and value as the output column. However, the key would become super-long at least 13 characters (if I decide to use Y N or other characters to represent the TRUE,FALSE,N/A values in the table).

Any other way?

2 Answers

Since we're using Java, the first thing that comes to mind is, create a class.

So, let's create a class to hold one row of your decision table.

public class DecisionRow {
    
    private final Boolean[] input;
    private final String output;
    
    public DecisionRow(Boolean[] input, String output) {
        this.input = input;
        this.output = output;
    }
    
    public boolean doesInputMatch(Boolean[] input) {
        for (int i = 0; i < input.length; i++) {
            if (this.input[i] != null && !this.input[i].equals(input[i])) {
                return false;
            }
        }
        return true;
    }

    public String getOutput() {
        return output;
    }

}

Next, we'll create a class to hold the decision tree;

public class DecisionTree {
    
    private List<DecisionRow> decisionTree;
    
    public DecisionTree() {
        this.decisionTree = createDecisionTree();
    }
    
    private List<DecisionRow> createDecisionTree() {
        List<DecisionRow> decisionTree = new ArrayList<>();
        
        Boolean[] values = new Boolean[] { true, false, false, false, false,
                false, false, false, false, true, null, null, false };
        decisionTree.add(new DecisionRow(values, "vanguard"));
        
        values = new Boolean[] { true, false, false, false, false,
                null, false, false, false, false, false, false, false };
        decisionTree.add(new DecisionRow(values, "jpmc"));
        
        return decisionTree;
    }
    
    public List<DecisionRow> getDecisionTree() {
        return decisionTree;
    }
    
    public DecisionRow getDecisionRow(Boolean[] values) {
        for (DecisionRow decisionRow : decisionTree) {
            if (decisionRow.doesInputMatch(values)) {
                return decisionRow;
            }
        }
        
        return null;
    }
    
}

You add as many rows to the decision tree as you need. Your N/A is represented by null.

Now, all you have to do is match the booleans to get the output String.

First, I like your Map idea. It should be easy to implement, understand and maintain.

Another idea would be to use 13-dimensional array:

String[][][][][][][][][][][][][]

Maybe 14 dimensions, I haven't thought it through yet

E.g. for 2 input columns:

String[][] table = new String[3][3];

table[0][0] = "a";
table[0][1] = "b";
table[0][2] = "c";

table[1][0] = "d";
table[1][1] = "e";
table[1][2] = "f";

table[2][0] = "g";
table[2][1] = "h";
table[2][2] = "i";

Corresponding to the map approach of:

map.put("--", "a");
map.put("-N", "b");
map.put("-Y", "c");

map.put("N-", "d");
map.put("NN", "e");
map.put("NY", "f");

map.put("Y-", "g");
map.put("YN", "h");
map.put("YY", "i");
Related