我有一个用例,需要解析键值对(用=
分隔)并将这些键值对放在LinkedHashMap
中。
我想忽略以下类型的String
String
不包含=
。 现在,我已经使用命令式样式和流方法解决了它。
以下是2个变体:
for
循环和大量if
public static Map<String, String> getMap1(String[] array) {
Map<String, String> map = new LinkedHashMap<>();
for (int i = 0; i < array.length; i++) {
String currentString = array[i];
int index = currentString.indexOf('=');
// ignoring strings that don't contain '='
if (index == -1) continue;
String key = currentString.substring(0, index).trim();
String value = currentString.substring(index + 1).trim();
// ignoring strings with empty key or value
if (key.length() == 0 || value.length() == 0) continue;
map.put(key, value);
}
return map;
}
Stream
s的解决方案-非常简洁的代码public static Map<String, String> getMap(String[] array) {
return Arrays.stream(array)
.filter(s -> s.indexOf('=') != -1) // ignore strings that don't contain '='
.filter(s -> s.substring(0, s.indexOf('=')).trim().length() != 0) // key should be present
.filter(s -> s.substring(s.indexOf('=') + 1).trim().length() != 0) // value should be present
.collect(Collectors.toMap(
s -> s.substring(0, s.indexOf('=')).trim(),
s -> s.substring(s.indexOf('=') + 1).trim(),
(first, second) -> second,
LinkedHashMap::new));
}
我在这里担心,因为在使用Stream
时,我多次调用indexOf
方法。 (对于大字符串,我可以一次又一次地重新计算同一件事。)
有没有一种方法可以避免通过indexOf
方法进行重新计算,从而使代码仍然干净。 (我知道谈论干净代码是非常主观的,但是我不想打开多个流,通过原始字符串数组进行循环,然后预先计算=
的索引,然后重新使用)。
再次将多个filter
合并到一个过滤器中似乎是一种选择,但这会使我的谓词非常难看。
(这是我想学习/改善的无所事事的结果)。
答案 0 :(得分:3)
那呢:
String[] array = {"aaa2=asdas","aaa=asdasd"};
LinkedHashMap<String, String> aaa = Arrays.stream(array)
.map(s -> s.split("=", 2))
.filter(s -> s.length == 2) // ignore strings that don't contain '='
.peek(s -> { s[0] = s[0].trim(); })
.peek(s -> { s[1] = s[1].trim(); })
.filter(s -> s[0].length() != 0) // key should be present
.filter(s -> s[1].length() != 0) // value should be present
.collect(Collectors.toMap(
s -> s[0],
s -> s[1],
(first, second) -> second,
LinkedHashMap::new));
答案 1 :(得分:0)
我将使用split而不是indexOf和StringUtils来检查您的键和值是否为空。
public static Map<String, String> getMap(String[] array) {
return Arrays.stream(array)
.filter(s -> s.contains("="))
.map(s -> s.split("="))
.filter(s -> s.length == 2 && isNotBlank(s[0]) && isNotBlank(s[1]))
.collect(Collectors.toMap(
s -> s[0].trim(),
s -> s[1].trim()));
}