我有一个以下字符串。我想将其转换为 map 列表,如下所示,
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}
]
它是通过 ),
进行分割,然后通过逗号来获取 map 元素。我尝试了以下有效的方法,
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());
有没有更好的方法来做到这一点?
最佳答案
AtomicInteger
在这里是多余的。它增加了更多的复杂性和更多的失败空间。
此外,Stream API
的规范 does not guarantee 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
转换提取到静态 util 方法中:
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());
关于java - 将字符串转换为 map 列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61102758/