【发布时间】:2019-04-16 00:36:07
【问题描述】:
我有一个用例,我需要解析键值对(由= 分隔)并将这些键值对放在LinkedHashMap 中。
我想忽略以下类型的Strings
- 键为空或仅包含空格
- 值为空或仅包含空格
- 那些不包含
=的Strings。
现在,我使用命令式风格和流也解决了它。
以下是 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;
}
使用Streams 的解决方案 - 非常干净的代码
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));
}
我在这里很担心,因为在使用Streams 时,我多次调用indexOf 方法。 (对于大字符串,我最终可以一次又一次地重新计算相同的东西)。
有没有一种方法可以避免indexOf 方法完成的重新计算,这样代码仍然是干净的。 (我知道谈论干净代码是非常主观的,但我不想打开多个流,循环遍历原始字符串数组,然后预先计算 = 的索引并重新使用它)。
再次将多个filters 合并到一个过滤器中似乎是一种选择,但这会使我的谓词变得非常丑陋。
(这是我在想学习/改进的地方闲逛的结果)。
【问题讨论】:
-
为什么不使用
split而不是indexOf?正如您所说,此代码还将在array[i]中为两个=中断:那些不包含=的字符串
标签: java optimization java-8 java-stream