Разбить строку на ключи и значения для построения карты

#java

#java

Вопрос:

У меня есть следующая строка: utm_campaign=some_campaignamp;utm_content=videoamp;utm_medium=paidsocialamp;utm_source=facebook" я хочу разделить ее на ключи / значения и поместить в HashMap:

 KEY: utm_campaign VALUE: some_campaign
...
etc
  

Кроме того, перед тем, как поместить ее в Map, я должен заменить utm на ga в этом методе:

 private String convertUtmToGa(String utm) {
        switch (utm) {
            case "utm_medium":
                return "ga:medium";
            case "utm_campaign":
                return "ga:campaign";
            case "utm_source":
                return "ga:source";
            case "utm_content":
                return "ga:adContent";
            default:
                return utm;
        }
    }
  

Итак, я должен получить карту следующим образом:

 ga:campaign=some_campaign, ga:adContent=video, ga:medium=paidsocial
  

Я попытался с:

 private Map<String, String> extractUtmMarks(String paramsString) {
        if (paramsString != null) {
            Map<String, String> params = new HashMap<>();
            String[] paramsAndValues = paramsString.split("amp;");

            for (String paramAndValue : paramsAndValues) {
                    String[] keyValueArray = paramAndValue.split("=");
                    if (keyValueArray.length == 2 amp;amp; !keyValueArray[1].isBlank() amp;amp; !isUtmMarkContainsMacro(keyValueArray[1])) {
                        String param = convertUtmMarkToGa(keyValueArray[0]);
                        if (!param.isBlank()) {
                            params.put(param, keyValueArray[1]);
                        }
                    }
            }
            return params;
        }
        return Collections.emptyMap();
    }
  

Но этот код выглядит не очень хорошо. Могу ли я получить лучшее решение?

Комментарии:

1. Что не так с тем, что вы сделали?

2. Этот код выглядит неточным и может привести к ошибкам из-за индексов.

3. Это не может привести к ошибкам. Вы проверяете это keyValueArray.length == 2 , поэтому он всегда будет иметь индекс 0 и индекс 1.

Ответ №1:

Использование потоков…

 import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;

    ...
    final String input = "utm_campaign=some_campaignamp;utm_content=videoamp;utm_medium=paidsocialamp;utm_source=facebook";

    final Map<String, String> map =
            Arrays.stream(input.split("amp;"))           // Stream of "K=V" strings
            .map(subString -> subString.split("="))   // Returns 2 element array -- {K,V}
            .collect(Collectors.toMap(tokens -> convertUtmToGa(tokens[0]), tokens -> tokens[1]));
  

Ответ №2:

Вы также можете использовать потоки, но если ваши методы работают, зачем их менять?

  • первое разделение на amp;
  • затем на =
 String v =
        "utm_campaign=some_campaignamp;utm_content=videoamp;utm_medium=paidsocialamp;utm_source=facebook";

Map<String, String> map = Arrays.stream(v.split("amp;"))
        .map(arr -> arr.split("="))
        .collect(Collectors.toMap(a -> a[0], a -> a[1]));

map.entrySet().forEach(System.out::println);
  

С принтами

 utm_campaign=some_campaign
utm_medium=paidsocial
utm_content=video
utm_source=facebook