Текущее решение с циклом for выглядит хорошо. Поскольку нужно различать только три случая, нет необходимости обобщать обработку.
Если будет больше случаев для различения, тогда может иметь смысл рефакторинг кода. Мой подход заключается в явном определении различных условий и соответствующей им обработки строк. Позвольте мне объяснить это, используя код из вопроса.
Прежде всего я определяю различные условия, используя перечисление.
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;
}
}
}
Используя это перечисление, я определяю соответствующие строковые процессоры:
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 + "|" }));
}
Исходя из этого, я могу выполнить всю обработку, используя запрошенную 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))));
}
Подход заключается в том, чтобы получить для строки соответствующий StringClassification
, а затем, в свою очередь, соответствующий строковый процессор. Строковые процессоры реализуют шаблон стратегии , предоставляя Function<String, List<String>>
, который отображает String
в List<String>
в соответствии с StringClassification
.
Быстрый пример:
public static void main(String[] args) {
List<String> list = Arrays.asList("123",
"1-2",
"0987654321098765432109876543211",
"098765432109876543210987654321a-b-c");
System.out.println(splitByWords(list));
}
Вывод:
{0=[123|], 1=[1-2|], 2=[0987654321098765432109876543211], 3=[098765432109876543210987654321a, b, c]}
Это позволяет легко добавлять или удалять условия и строковые процессоры.