0

I have a string in the form "1=xyz,2=zyx,3=blah", and an object

public class Foo{
    String a,b,c
    /*gets and sets*/
}

I'd like to instantiate this object so that a = xyz, b = zyx, and c = blah. What I have so far is,

for(String[] split1 : originalString.split(","){
    for(String[] split2 : split1.split("="){
        if(split2[0] == 1){foo.setA(split2[1])}
        if(split2[0] == 2 {...}
    }
}

And what I want to know is, is there a cleaner way to do this than with a bajillion if statements? Is there a way to create a Map between the keys in the original list with setters in my pojo?

I found some older questions on this, but I was wondering if java 8 might have added something for this. I don't want to use Reflection (nor should I)

Steve
  • 4,457
  • 12
  • 48
  • 89
  • Do a,b,c need to be different variables, or could they be a list? – jrtapsell Oct 20 '17 at 17:30
  • Since you have a index you can interface a Setter class to an array and use just allSetters[split2[0]].setValue(split2[1]), you would replace the ifs by an array getter – Marcos Vasconcelos Oct 20 '17 at 17:35
  • Use can use an [`Introspector`](https://docs.oracle.com/javase/7/docs/api/java/beans/Introspector.html) to do this in a couple of lines of code. – Boris the Spider Oct 20 '17 at 17:39
  • Possible duplicate of [Assigning variables with dynamic names in Java](https://stackoverflow.com/questions/6729605/assigning-variables-with-dynamic-names-in-java) –  Oct 20 '17 at 17:40
  • Also, see https://stackoverflow.com/questions/276555/setting-variables-by-name-in-java –  Oct 20 '17 at 17:40
  • No doubt you could come up with an approach revolving around associating indexes with method references, but I don't see anything to recommend such an approach over an ordinary `switch` statement. I do prefer the `switch` to a bunch of `if`s, though. – John Bollinger Oct 20 '17 at 17:43
  • @jrtapsell separate, they only seem similar here for the purpose of the example – Steve Oct 20 '17 at 17:43
  • 1
    If you're doing stuff that's substantially dynamic, it may be simpler to use Groovy. – chrylis -cautiouslyoptimistic- Oct 20 '17 at 19:48

3 Answers3

2

Yes, you can use a Map<String, BiConsumer<Foo, String>>:

public class StringProcessor {
    private final Map<String, BiConsumer<Foo, String>> setMethods;

    public StringProcessor() {
        Map<String, BiConsumer<Foo, String>> methodMap = new HashMap<>();
        methodMap.put("a", Foo::setA);
        methodMap.put("b", Foo::setB);
        methodMap.put("c", Foo::setC);

        this.setMethods = Collections.unmodifiableMap(methodMap);
    }

    // ...

    public void processString(String originalString,
                              Foo foo) {

        for (String[] split1 : originalString.split(",")) {
            for (String[] split2 : split1.split("=")) {
                BiConsumer<Foo, String> setMethod = setMethods.get(split2[0]);
                setMethod.accept(foo, split2[1]);
            }
        }

    }
}

You could also use reflection, but that is best avoided, as reflection makes errors much harder to detect and it is less likely to be optimized at runtime by the JIT.

VGR
  • 40,506
  • 4
  • 48
  • 63
0

I created a Map like 1="a", 2="b", 3="c", and used that to translate the keys into the pojo's field names.

Then I used the following from Gson

Gson gson = new Gson();
JsonElement jsonElement = gson.toJsonTree(responseMap);
Foo trade = gson.fromJson(jsonElement, Foo.class);

If I'd been allowed to use groovy, I'd simply use the default map-based constructor. Props to @chrylis for suggesting that approach.

Steve
  • 4,457
  • 12
  • 48
  • 89
0

can use Regular Expression to blank out the not needed characters from the input string and then splitting it. Note the String elements in the output array might need trimming.

import java.util.regex.*;

public class StringRegex{
 public static void main(String[] args){
  String input = "1=xyz,2=zyx,3=blah";
  String notNeeded = "([1234567890=])";      //characters not needed 0-9 and =

  Pattern p = Pattern.compile(notNeeded);
  Matcher m = p.matcher(input);

  String output = m.replaceAll(" ");  //blank out the notNeeded characters
  System.out.println(output);         //gives:   xyz,  zyx,  blah

  String[] outputArr = output.split(",");

  for (String s:outputArr)
    System.out.println(s);
 }
}
Saurabh
  • 23
  • 4