Home > Enterprise >  A way to link a string of digits to two or more string values, like an enum
A way to link a string of digits to two or more string values, like an enum

Time:11-09

I have strings of digits ('numbers') that correspond to strings, not all matches are unique, but the numbers are. Nothing changes, it's all constant. Something like this:

10023 - "Hugo" - "Boss"
023 - "Big" - "Boss"
1230 - "Hugo" - "A or B"
// ...and about twenty more like that

what i want, is to be able to receive a string of digits, and then get the two strings for that.

The enum way isn't neat, because i cannot call the enum a number (needs a leading non-digit), otherwise i could go with the whole song-and-dance of defining an enum and then getting the values by looking for the right one with Enum.valueOf(), and the method way is not neat because it is ugly and unreadable during definition.

public class detailsForNumber {
   public String first;
   public String second;
   public detailsForNumber(String number) {
   if (number == "10023") {
      first = "Hugo";
      second = "Boss";
   } else if (number == "023")
//.....and so on 

//Then i could later and somewhere else go:

Somewhere.detailsForNumber dFN = Somewhere.detailsForNumber("023");
System.out.println(dFN.first); // Prints 'Big'

   

is there a readable way to define this relationship somewhere and then a reasonable way to get the strings out of there?

Ideally it would be a non-headache to later add a third string, or have a non-digit character in the 'number', but there will be no changes at runtime.

CodePudding user response:

If it's all constant and static data then you may use a simple switch:

class Name {
    private String first;
    private String second;

    private Name(final String first, final String second) {
        this.first = first;
        this.second = second;
    }

    public String getFirst() { return first; }
    public String getSecond() { return second; }

    public static Name forNumber(final String number) {
        switch (number) {
            case "10023": return new Name("Hugo", "Boss");
            case "023":   return new Name("Big", "Boss");
            case "1230":  return new Name("Hugo", "A or B");

            default: return null;
        }
    }

};

class Main {
    public static void main(String args[]) {
        final String number = "023";
        final Name n = Name.forNumber(number);
        if (n == null) {
            System.out.println("Not found");
            return;
        }
        System.out.printf("%s -> {%s, %s}\n", number, n.getFirst(), n.getSecond());
    }
}

See online

If the data is loaded at runtime, you may use HashMap.

CodePudding user response:

I would go with creating a class that has three attributes.

  1. key of type String (the leading zero unique numbers that you have)
  2. str1 the String value 1
  3. str2 the String value 2

And then create another class that keeps all your Data. You can then filter using streams.

For example:

public class Data
{
    private String key;
    private String str1;
    private String str2;

    // Getters, setters, equals...
    
}

public class DataList
{
    private List<Data> list = new ArrayList<>();
    
    public boolean addDataToList(Data newData)
    {
        boolean isDuplicate = list.stream().anyMatch(data -> data.getKey().equals(newData.getKey()));
        
        if(isDuplicate)
        {
            return false;
        }
        
        list.add(newData);
        return true;
    }

    public Data getThroughKey(String key)
    {
        Optional<Data> opt = list.stream().filter(data -> data.getKey().equals(key)).findFirst();

        // Or handle it 
        return opt.orElse(null);
    }
    
    // Getters, setters and whatever else you need
}

You could also use a Set which takes care of duplicates without you explicitly checking. But you must override the equals() and hashCode() functions in your Data class. I do not know which one of them is more efficient. That's a story for another question.

CodePudding user response:

Try this.

public enum DetailsForNumber {
    E10023("10023", "Hugo", "Boss"),
    E023("023", "Big", "Boss"),
    E1230("1230", "Hugo", "A or B");
    
    public final String number, first, second;
    private static final Map<String, DetailsForNumber> map = new HashMap<>();
    static {
        for (DetailsForNumber e : values())
            map.put(e.number, e);
    }
    
    private DetailsForNumber(String number, String first, String second) {
        this.number = number;
        this.first = first;
        this.second = second;
    }
    
    public static DetailsForNumber get(String number) {
        return map.computeIfAbsent(number,
            k -> { throw new IllegalArgumentException("number"); });
    }
}

public static void main(String[] args) {
    DetailsForNumber dFN = DetailsForNumber.get("023");
    System.out.println(dFN.first);
}

output:

Big

CodePudding user response:

using enum like below:

public enum NumberDetails {
    // it's a demo, you can define the name more meaningful.
    NUMBER_1("10023", "Hugo", "Boss"),
    NUMBER_2("023", "Big", "Boss"),
    NUMBER_3("1230", "Hugo", "A or B");

    private String number;
    private String first;
    private String second;

    static Map<String, NumberDetails> CACHE_MAP = Arrays.stream(values())
                    .collect(Collectors.toMap(NumberDetails::getNumber, it -> it, (a, b) -> a));

    public static NumberDetails from(String number) {
        return CACHE_MAP.get(number);
    }

    NumberDetails(String number, String first, String second) {
        this.number = number;
        this.first = first;
        this.second = second;
    }

    public String getNumber() {
        return number;
    }

    public String getFirst() {
        return first;
    }

    public String getSecond() {
        return second;
    }
}

and a simple usage:

public class NumberDetailsTest {
    public static void main(String[] args) {
        System.out.println(NumberDetails.from("023").getFirst());
    }
}
  •  Tags:  
  • java
  • Related