Eu tenho um caso de uso onde eu preciso analisar pares chave-valor (separados por =
) e colocar esses pares de valor-chave em um LinkedHashMap
.
Eu quero ignorar o seguinte tipo de String
s
- chave é vazio ou contém apenas espaços
- valor é vazio ou contém apenas espaços
- esses
String
s que não contêm um=
.
Agora, eu ter resolvido isso usando o estilo imperativo e usando correntes também.
O que se segue são as 2 variantes:
Solução pelo estilo iterativo - for
circuito e muitaif
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;
}
Solução que usa Stream
s - código limpo bastante
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));
}
Eu estou preocupado aqui porque enquanto estiver usando Stream
s, eu estou chamando o indexOf
método várias vezes. (E para as grandes cadeias, eu posso acabar-se recalcular a mesma coisa uma e outra vez).
Existe uma maneira que eu possa evitar a re-cálculo feito pelo indexOf
método de tal forma que o código ainda está limpo. (Eu sei que falando-código limpo é muito subjetivo, mas eu quero fazer não quer abrir múltiplos fluxos, de percorrer a string-matriz original e, posteriormente, pré-cálculo dos índices de =
e re-utilizar esse).
Clubbing vários filter
s em um único filtro parecem novamente para ser uma opção, mas que faria o meu predicado muito feio.
(Este é um resultado da minha reflexão ocioso onde eu quiser aprender / melhorar).
E quanto a isto:
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));