Можно ли сократить код с помощью цикла?
Можно ли сократить такой код, например, с помощью цикла?
boolean isMorning = valueLn.text().contains("Утро");
boolean isDay =valueLn.text().contains("День");
boolean isEvening =valueLn.text().contains("Вечер");
boolean isNight =valueLn.text().contains("Ночь");
if (isMorning){ iterationCount = 3; }
else if (isDay) {iterationCount = 2;}
else if (isEvening){iterationCount =1;}
else if (isNight){iterationCount = 0;}
Ответы (1 шт):
Исходный код следует не "уменьшить"/сократить, а упростить -- убрать повторяющиеся элементы, и сократить логические операторы, в том числе и с помощью циклов или Stream API.
К примеру, нет необходимости вызывать четыре раза метод contains
и заводить четыре булевых переменных, если в дальнейшем результат определяется через if / else-if
и зависит только от одного флажка.
Например, проще реализовать отдельное перечисление, которое обрабатывало бы входную строку и содержало необходимые данные:
public enum DayPart {
MORNING("Утро", 3),
DAY("День", 2),
EVENING("Вечер", 1),
NIGHT("Ночь", 0);
private final String ruAlias;
private final int iterationCount;
private DayPart(String alias, int count) {
this.ruAlias = alias;
this.iterationCount = count;
}
public int getIterationCount() { return this.iterationCount;}
public static DayPart byAlias(String alias) {
for (var v : DayPart.values()) {
if (alias.contains(v.ruAlias)) {
return v;
}
}
return null; // или выбросить исключение
}
}
Соответственно, необходимые данные вынесены в отдельный класс и логика обработки строки вынесена в отдельный статический метод этого класса, где используется цикл.
Таким перечислением проще пользоваться.
int iterCount = DayPart.byAlias(valueLn.text()).getIterationCount();
Аналогично, вместо циклов можно было бы применить Stream API + Optional
/ OptionalInt
, чтобы правильнее представить "пустое" значение, не найденное во входной строке alias
.
// enum DayPart
public static OptionalInt countByAlias(String alias) {
return Arrays.stream(DayPart.values())
.filter(v -> alias.contains(v.ruAlias)) // Stream<DayPart>
.findFirst() // Optional<DayPart>
.map(v -> OptionalInt.of(v.iterationCount))
.orElseGet(OptionalInt::empty);
}
Разумеется, если главная задача -- просто сократить код, можно обойтись и без отдельного класса, но всё равно следует вынести логику в отдельный метод:
public static getIterCount(String dayPart) {
if (dayPart.contains("Утро")) { // лучше использовать некую именованную константу
return 3;
} else if (dayPart.contains("День")) {
return 2;
} else if (dayPart.contains("Вечер")) {
return 1;
}
return 0; // значение по умолчанию, не только для ночи
}
Ещё один вариант с использованием обновлённого switch
-выражения с сопоставлением шаблонов (Java 21+) и упрощённой логикой, когда 0 всегда возвращается по умолчанию:
public static int getIterCount(Object o) {
return switch (o) {
case String s when s.contains("Утро") -> 3;
case String s when s.contains("День") -> 2;
case String s when s.contains("Вечер") -> 1;
default -> 0;
};
}