jon lee
jon lee

Reputation: 887

Java lookup table design for multiple values

I need to create a lookup table in Java to return a value based on multiple parameters.

For example:

['THE VALUE I NEED', 'PARAM A', 'PARAM B' ,'PARAM C']

So based on the 3 params PARAM A, B. C, I need to retrieve a value.

I was looking at doing this with an Enum, but the the same key can be duplicated for example:

[RESULT 1, 'A' , 'B', 'C']
[RESULT 1, 'C' , 'B', 'C']
[RESULT 2, 'B' , 'C', 'A']

Whats the best way to implement this lookup table in Java, allowing for the duplicate key with different parameter configuration?

Upvotes: 1

Views: 5462

Answers (2)

PeterK
PeterK

Reputation: 1723

You could use a nested class and a Map for this, in case you need a solution more flexible than an enum.

The key here is to create your own lightweight data class, in this case Data that would wrap around the values you want to map on, a, b and c here. You will need to overwrite the equals and hashCode function to incorporate all fields. Also, I would advice making these fields final. Changes to these fields will not automatically update the HashTable and might yield unexpected results. If you would need to create this lookup table once, you might want to look into wrapping the resulting map in a Collections.unmodifiableMap, to stop any of your classes from accidentally modifying the underlying collection.

  public static void main(String... args) {
    Map<Data, String> map = new HashMap<>();
    map.put(new Data("1", "A", "B"), "Value A");
    map.put(new Data("2", "F", "£"), "Value B");
    map.put(new Data("D", "A", "B"), "Value C");

    map.get(new Data("1", "A", "B")); // "Value A"

  }

Data class:

  public static class Data {
    private final String a;
    private final String b;
    private final String c;

    public Data(String a, String b, String c) {
      this.a = a;
      this.b = b;
      this.c = c;
    }

    public String getA() {
      return a;
    }

    public String getB() {
      return b;
    }

    public String getC() {
      return c;
    }

    @Override
    public int hashCode() {
      return a.hashCode() + 31 * b.hashCode() + 13 * c.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
      return obj instanceof Data
               && Objects.equals(a, ((Data)obj).a)
               && Objects.equals(b, ((Data)obj).b)
               && Objects.equals(c, ((Data)obj).c);
    }
  }

Upvotes: 1

SME_Dev
SME_Dev

Reputation: 1890

You can stick with the enum, if your variables/parameters are static:

public enum LookupElement{

    ELEM_1("A","B","C", 1),
    ELEM_2("C","B","C", 1),
    ELEM_3("B","C","A", 2);

    private final String a;
    private final String b;
    private final String c;
    private final int value;

    LookupElement(String a, String b, String c, int v){
        this.a = a;
        this.b = b;
        this.c = c;        
        this.value = v;
    }

    public static LookupElement getByValue(int v){
        for(LookupElement e : values()){
            if(e.value == v) return e;
        }
        return null;
    }

    public static LookupElement getByParams(String a, String b, String c){
        for(LookupElement e : values()){
            if(e.a.equals(a) && e.b.equals(b) && e.c.equals(c)) return e;
        }
        return null;
    }
}

Upvotes: 3

Related Questions