Atualmente, eu tenho esse método, o que eu quero converter para um estilo de fluxo de Java 8 (eu tenho pouco de prática com este API btw, esse é o propósito deste pequeno exercício):
private static Map<Integer, List<String>> splitByWords(List<String> list) {
for (int i = 0; i < list.size(); i++) {
if(list.get(i).length() > 30 && list.get(i).contains("-")) {
mapOfElements.put(i, Arrays.stream(list.get(i).split("-")).collect(Collectors.toList()));
} else if(list.get(i).length() > 30) {
mapOfElements.put(i, Arrays.asList(new String[]{list.get(i)}));
} else {
mapOfElements.put(i, Arrays.asList(new String[]{list.get(i) + "|"}));
}
}
return mapOfElements;
}
Isto é o que Ive tenho até agora:
private static Map<Integer, List<String>> splitByWords(List<String> list) {
Map<Integer, List<String>> mapOfElements = new HashMap<>();
IntStream.range(0, list.size())
.filter(i-> list.get(i).length() > 30 && list.get(i).contains("-"))
.boxed()
.map(i-> mapOfElements.put(i, Arrays.stream(list.get(i).split("-")).collect(Collectors.toList())));
//Copy/paste the above code twice, just changing the filter() and map() functions?
No caminho "à moda antiga", eu só preciso de uma for
iteração para fazer tudo o que precisa sobre minhas condições. Existe uma maneira de conseguir isso usando a API do córrego ou, se quero cumpri-lo, eu tenho que repetir o código acima apenas mudando o filter () e mapa () condições, portanto, ter três for
iterações?
A solução atual com o loop for parece ser bom. Como você tem que distinguir apenas três casos, não há necessidade de generalizar o processamento.
Deveria haver mais casos de distinguir, então ele poderia fazer sentido para refatorar o código. Minha abordagem seria definir explicitamente as diferentes condições e seu processamento corda correspondente. Deixe-me explicar-lo usando o código da questão.
Primeiro de tudo eu estou definindo as diferentes condições usando um enum.
public enum StringClassification {
CONTAINS_HYPHEN, LENGTH_GT_30, DEFAULT;
public static StringClassification classify(String s) {
if (s.length() > 30 && s.contains("-")) {
return StringClassification.CONTAINS_HYPHEN;
} else if (s.length() > 30) {
return StringClassification.LENGTH_GT_30;
} else {
return StringClassification.DEFAULT;
}
}
}
Usando esta enumeração que definem os processadores de cordas correspondentes:
private static final Map<StringClassification, Function<String, List<String>>> PROCESSORS;
static {
PROCESSORS = new EnumMap<>(StringClassification.class);
PROCESSORS.put(StringClassification.CONTAINS_HYPHEN, l -> Arrays.stream(l.split("-")).collect(Collectors.toList()));
PROCESSORS.put(StringClassification.LENGTH_GT_30, l -> Arrays.asList(new String[] { l }));
PROCESSORS.put(StringClassification.DEFAULT, l -> Arrays.asList(new String[] { l + "|" }));
}
Com base nesta posso fazer todo o processamento usando o solicitado IntStream
:
private static Map<Integer, List<String>> splitByWords(List<String> list) {
return IntStream.range(0, list.size()).boxed()
.collect(Collectors.toMap(Function.identity(), i -> PROCESSORS.get(StringClassification.classify(list.get(i))).apply(list.get(i))));
}
A abordagem é recuperar para uma corda a apropriada StringClassification
e, em seguida, por sua vez, o processador seqüência correspondente. Os processadores de cordas estão implementando o padrão de estratégia , proporcionando um Function<String, List<String>>
que mapeia uma String
a uma List<String>
de acordo com o StringClassification
.
Um exemplo rápido:
public static void main(String[] args) {
List<String> list = Arrays.asList("123",
"1-2",
"0987654321098765432109876543211",
"098765432109876543210987654321a-b-c");
System.out.println(splitByWords(list));
}
A saída é:
{0=[123|], 1=[1-2|], 2=[0987654321098765432109876543211], 3=[098765432109876543210987654321a, b, c]}
Isto torna mais fácil para adicionar ou remover as condições e processadores de cordas.