У меня есть строка в форме "1 = XYZ, 2 = ZYX, 3 = Blah", и объект

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

Я хотел бы создать экземпляр этого объекта, чтобы a = xyz, b = zyx и c = blah. То, что у меня есть,

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

И что я хочу знать, есть ли более чистый способ сделать это, чем с баджиллионными заявлениями? Есть ли способ создать карту между ключами в исходном списке с помощью сеттеров в моем pojo?

Я нашел некоторые старые вопросы по этому вопросу, но мне было интересно, если бы Java 8 мог добавить что-то для этого. Я не хочу использовать Reflection (и я не должен)

0
Steve 20 Окт 2017 в 20:25

3 ответа

Лучший ответ

Я создал карту типа 1 = "a", 2 = "b", 3 = "c" и использовал ее для перевода ключей в имена полей pojo.

Тогда я использовал следующее от Gson

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

Если бы мне было позволено использовать groovy, я бы просто использовал конструктор по умолчанию на основе карт. Рекомендую @chrylis предложить этот подход.

0
Steve 20 Окт 2017 в 20:25

Да, вы можете использовать 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]);
            }
        }

    }
}

Вы также можете использовать рефлексию, но этого лучше избегать, поскольку рефлексия значительно усложняет обнаружение ошибок и снижает вероятность ее оптимизации во время выполнения JIT.

2
VGR 20 Окт 2017 в 17:44

Можно использовать Регулярное выражение, чтобы убрать ненужные символы из входной строки и затем разделить ее. Обратите внимание, что элементы String в выходном массиве могут нуждаться в обрезке.

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);
 }
}
0
Saurabh 22 Окт 2017 в 12:24