Преобразовать строку в список карты - PullRequest
0 голосов
/ 08 апреля 2020

У меня есть следующая строка. Я хочу преобразовать его в список карт, как показано ниже,

String esConnectionPropertiesStr = "ID1, 701, REST, 0, $PROJECT_ID),\n" +
               "ID2, 702, ES_USERNAME, 0, $PROJECT_ID),\n" +
               "ID3, 703, ES_PASSWORD, 0, $PROJECT_ID),\n" +
               "ID4, 704, ES_HOST, 0, $PROJECT_ID";

Вывод:

[ 
    {1=ID1, 2=701, 3= ES_USERNAME, 4= 0, 5= $PROJECT_ID}, 
    {1=ID2, 2=702, 3= ES_PASSWORD, 4= 0, 5= $PROJECT_ID},
    {1=ID3, 2=703, 3=ES_HOST, 4= 0, 5= $PROJECT_ID},
    {1=ID4, 2=704, 3= ES_PORT, 4= 0, 5=$PROJECT_ID} 
]

Он разделяется на ),, а затем через запятую, чтобы получить элементы карты. Я попытался следовать, который работает,

AtomicInteger index = new AtomicInteger(0);
Arrays.stream(esConnectionPropertiesStr.split("\\),"))
        .map(e -> Arrays.stream(e.split(","))
                .collect(Collectors.toMap(n1 -> index.incrementAndGet(), s -> s)))
        .peek(i -> index.set(0))
        .collect(Collectors.toList());

Есть ли лучший способ сделать это ??

1 Ответ

1 голос
/ 09 апреля 2020

AtomicInteger здесь избыточно. Это добавляет больше сложности и больше места для неудачи. Более того, спецификация Stream API не гарантирует исполнения Stream::peek.

Это наивное (хотя и довольно длинное) решение:

List<Map<Integer, String>> resultMap =
        Arrays.stream(esConnectionPropertiesStr.split("\\),"))
              .map(row -> Arrays.stream(row.split(","))
                                .collect(collectingAndThen(toList(), 
                                         list ->IntStream.range(0, list.size())
                                                         .boxed()
                                                         .collect(toMap(identity(), list::get)))))
              .collect(toList());

Хотя вышеприведенное решение работает, ИМХО оно не читабельно. Я извлек бы преобразование list-to-map в метод подсчета stati c:

class Utils { // 
    public static Map<Integer, String> toIndexedMap(List<String> list) {
        return IntStream.range(0, list.size())
                        .boxed()
                        .collect(toMap(identity(), list::get));
}

, а затем использовал бы следующие служебные методы:

List<Map<Integer, String>> result =
        Arrays.stream(esConnectionPropertiesStr.split("\\),"))
              .map(row -> Arrays.stream(row.split(","))
                                .collect(collectingAndThen(toList(), Utils::toIndexedMap)))
              .collect(toList());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...