У меня есть сценарий использования, когда мне нужно проанализировать пары ключ-значение (разделенные =
) и поместить эти пары ключ-значение в LinkedHashMap
.
Я хочу игнорировать следующий тип ключа String
s
- пуст или содержит только пробелы
- значение пусто или содержит только пробелы
- те
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
s,Я вызываю метод indexOf
несколько раз.(И для больших строк я могу в конечном итоге пересчитывать одно и то же снова и снова).
Есть ли способ, которым я могу избежать повторного вычисления, сделанного методом indexOf
в такомспособ, которым код все еще чист.(Я знаю, что говорить о чистом коде очень субъективно, но я не хочу открывать несколько потоков, проходить через исходный строковый массив, а затем предварительно вычислять индексы =
и повторно использовать это).
Объединение нескольких filter
s в один фильтр снова кажется вариантом, но это сделало бы мой предикат довольно уродливым.
(Это результат моих бесполезных размышлений, когда я хочуузнать / улучшить).