Преобразование java-карты в пользовательскую строку key = value

У меня есть TreeMap<String,String>, который мне нужно преобразовать в URI-подобную строку, а затем обратно в Map. Мне нужно установить пользовательские разделители.

Есть ли какой-нибудь инструмент (Guava, Apache commons?), который может сделать это для меня? Я знаю, я могу писать простые циклы, но я ищу однострочный:)

Например

key    value
key1   val1
key2   val2

key1_val1|key2_val2

Ответ 1

В соответствии с http://davidtulig.com/blog/introduction-to-google-guava-s-joiner-class/ вы можете сделать это в guava через

 String string = Joiner.on("|").withKeyValueSeparator("_").join(map);

Противоположность также доступна через

 Map<String, String> map = Splitter.on("|").withKeyValueSeparator("_").split(string);

Ответ 2

его не guava или apache commons, и это цикл, но помимо создания экземпляра строкового конструктора это один лайнер:

for (Entry<String,String> entry : myMap.entrySet()) {
    sb.append(entry.getKey() + separator + entry.getValue() + "\n");
}

Ответ 3

Использование Java8:

private static Map<String, String> prepareMap() {
    Map<String, String> map = new LinkedHashMap<>();
    map.put("key1", "val1");
    map.put("key2", "val2");
    return map;
}

@Test
public void toStr() {
    assertEquals("key1_val1|key2_val2", prepareMap().entrySet().stream()
            .map(e -> e.getKey() + "_" + e.getValue())
            .collect(Collectors.joining("|")));
}

@Test
public void toStrFunction() {
    assertEquals("key1_val1|key2_val2", joiner("|", "_").apply(prepareMap()));
}

private static Function<Map<String, String>, String> joiner(String entrySeparator, String valueSeparator) {
    return m -> m.entrySet().stream()
            .map(e -> e.getKey() + valueSeparator + e.getValue())
            .collect(Collectors.joining(entrySeparator));
}

@Test
public void toMap() {
    assertEquals("{key1=val1, key2=val2}", Stream.of("key1_val1|key2_val2".split("\\|"))
            .map(e -> e.split("_", 2))
            .collect(Collectors.toMap(e -> e[0], e -> e.length > 1 ? e[1] : null)).toString());
}

@Test
public void toMapFunction() {
    assertEquals("{key1=val1, key2=val2}", splitter("\\|", "_").apply("key1_val1|key2_val2").toString());
}

private static Function<String, Map<String, String>> splitter(String entrySeparator, String valueSeparator) {
    return s -> Stream.of(s.split(entrySeparator))
            .map(e -> e.split(valueSeparator, 2))
            .collect(Collectors.toMap(e -> e[0], e -> e.length > 1 ? e[1] : null));
}

Ответ 4

В java 8 и выше есть другой способ без внешних зависимостей: используйте StringJoiner:

    List<String> cities = Arrays.asList("Milan", 
                                        "London", 
                                        "New York", 
                                        "San Francisco");

    String citiesCommaSeparated = String.join(",", cities);

    System.out.println(citiesCommaSeparated);


    //Output: Milan,London,New York,San Francisco

Кредиты и пример перейдите в этот URL (https://reversecoding.net/java-8-convert-list-string-comma/)