waynewingorc
waynewingorc

Reputation: 209

Mapping between class fields and a String value

I have a Config class:

public class Config {
  private float arg1;
  private float arg2;
  private boolean flag;
  ...
}

There's a need to

Apparently I'll need to have a 2-way-mapping between the class field (e.g. arg1) to its corresponding http param field String value (e.g. a1)).
I can't think of a very maintainable way for the mapping. Easiest way would be:

String serialize(Config config){
  return "a1:" + config.arg1 + "|" + "a2:" + config.arg2 + "|" + "fl:" + config.flag;
}

Config deserialize(String configStr){
  Config config = new Config();

  for (String param : StringUtils.split(configStr, '|')) {
    final String[] fields = StringUtils.split(param, ':');
    final String value = fields[1];

    switch (fields[0]) {
      case "a1" -> config.arg1 = Float.parseFloat(value);
      case "a2" -> config.arg2 = Float.parseFloat(value);
      case "fl" -> config.flag = Boolean.parseBoolean(value);
    }
  }

  return config;
}

But with this approach I'll have to maintain the hard coding mapping in both methods, which doesn't look nice or clear to me.
Wondering if anyone has a better idea?

Upvotes: 1

Views: 650

Answers (1)

Oleg Cherednik
Oleg Cherednik

Reputation: 18255

You can use json (the best one on my opinion)

public static void main(String... args) throws JsonProcessingException {
    Config config = new Config();
    config.arg1 = 0.1f;
    config.arg2 = 0.5f;
    config.flag = true;

    ObjectMapper mapper = new ObjectMapper();
    String json = mapper.writeValueAsString(config);
    Config res = mapper.readValue(json, Config.class);
}

public static class Config {
    @JsonProperty("a1")
    private float arg1;
    @JsonProperty("a2")
    private float arg2;
    @JsonProperty("fl")
    private boolean flag;
}

You can use Properties class.

public static void main(String... args) throws IOException {
    Config config = new Config();
    config.arg1 = 0.1f;
    config.arg2 = 0.5f;
    config.flag = true;

    File file = new File("foo.properties");
    file.delete();
    file.createNewFile();

    try (OutputStream out = new FileOutputStream(file, false)) {
        config.store(out);
    }

    Config res = null;

    try (InputStream in = new FileInputStream(file)) {
        res = Config.load(in);
    }
}

public static class Config {

    private static final String A1 = "a1";
    private static final String A2 = "a2";
    private static final String FL = "fl";

    private float arg1;
    private float arg2;
    private boolean flag;

    public void store(OutputStream out) throws IOException {
        Properties properties = new Properties();
        properties.setProperty(A1, String.valueOf(arg1));
        properties.setProperty(A2, String.valueOf(arg2));
        properties.setProperty(FL, String.valueOf(flag));
        properties.store(out, "Some description");
    }

    public static Config load(InputStream in) throws IOException {
        Properties properties = new Properties();
        properties.load(in);

        Config config = new Config();
        config.arg1 = Float.parseFloat(properties.getProperty(A1, String.valueOf(0.f)));
        config.arg2 = Float.parseFloat(properties.getProperty(A2, String.valueOf(0.f)));
        config.flag = Boolean.parseBoolean(properties.getProperty(FL, String.valueOf(false)));

        return config;
    }

}

foo.properties

#Some description
#Fri Oct 28 06:53:11 MSK 2022
a1=0.1
a2=0.5
fl=true

You can use Scanner to save as String as File

public static void main(String... args) throws IOException {
    Config config = new Config();
    config.arg1 = 0.1f;
    config.arg2 = 0.5f;
    config.flag = true;

    String str = config.serialize();
    Config res = Config.deserialize(str);
}

public static class Config {

    private static final String A1 = "a1";
    private static final String A2 = "a2";
    private static final String FL = "fl";
    private static final String DELIMITER = ":";

    private float arg1;
    private float arg2;
    private boolean flag;

    public String serialize() throws IOException {
        StringBuilder buf = new StringBuilder();
        buf.append(A1).append(DELIMITER).append(arg1).append('\n');
        buf.append(A2).append(DELIMITER).append(arg2).append('\n');
        buf.append(FL).append(DELIMITER).append(flag).append('\n');
        return buf.toString();
    }

    public static Config deserialize(String str) {
        Scanner scan = new Scanner(str);
        scan.useDelimiter(DELIMITER + "|\\n");
        scan.useLocale(Locale.ENGLISH);

        Config config = new Config();

        while (scan.hasNext()) {
            switch (scan.next()) {
                case A1: config.arg1 = scan.nextFloat(); break;
                case A2: config.arg2 = scan.nextFloat(); break;
                case FL: config.flag = scan.nextBoolean(); break;
            }
        }

        return config;
    }

}

Upvotes: 1

Related Questions