Замена if на switch
Замена if else на switch
Доброго времени суток. Нуждаюсь в помощи с лабораторной работой. Задание: написать программу.
Замена конструкции switch словарем
Здравствуйте форумчане! Есть задача вывести словами трехзначное число(325 -> ТристаДвадцатьПять.
Замена if на switch
Задача. Это нужно сделать с помощью switch. ( Для натурального числа k вывести фразу “Мы нашли k.
Замена switch на if
Задание: Заменить в примере оператор switch структурой операторов if. Вопрос: Как можно заменить.
![]()
3638 / 2970 / 918
Регистрация: 05.07.2013
Сообщений: 14,220
switch можно использовать, когда одна переменная может принимать много значений. У тебя разные переменные и дублирующийся код.
Регистрация: 27.09.2013
Сообщений: 43
Не тот код, вот здесь нужно ifы заменить как-то.
А как тут замену произвести, ведь тут ifы в цикле уже (в цикле do. while)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
do { doPlayerMove(field); if (isWin(field, 'X')) { System.out.println("Congrats. You are winner!"); break; } if (isDraw(field)) { System.out.println("Oh.. It's draw! See you soon."); break; } drawField(field); doAIMove(field); if (isWin(field, 'O')) { System.out.println("Sorry. You are loser!"); break; } if (isDraw(field)) { System.out.println("Oh.. It's draw! See you soon."); break; } drawField(field); } while(true);
Регистрация: 27.09.2013
Сообщений: 43
Пытаюсь эти ифы в отдельный метод вынести, что ли, пишет ошибку:
219 / 178 / 79
Регистрация: 13.04.2014
Сообщений: 669
в Java нужно указывать тип входных параметров
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
Помогаю со студенческими работами здесь
Замена if-ов на switch case
В общем, было такое задание: Дана строка. Найдите в этой строке второе вхождение буквы f и.

Замена большого Switch
Привет, взглянув чуть-чуть наперед, и осознав что код может стать куда больше, появилась.

Замена switch/case
Здравствуйте, я написал программу, теперь хочу чтобы по вводу в консоль 1 у меня выполнялся вот.
Замена switch полиморфизмом
Здравствуйте. Читаю в данный момент книгу по рефакторингу, решил посмотреть свой старый код и.

Оправдана ли замена If на Switch
Всем привет! Я получаю ответ от сервера: string killer; killer = new.

Замена чисел на символы (switch)
Написать программу замены введенного числа от 0 до 9 соответствующим символом (1=! 2=@ . ) с.
Оператор switch
В отличие от операторов if-then и if-then-else, оператор switch применим к известному числу возможных ситуаций. Можно использовать простые типы byte, short, char, int. Также можно использовать Enum и String (начиная с JDK7), и специальные классы, которые являются обёрткой для примитивных типов: Character, Byte, Short, Integer.
Дублирование значений case не допускается. Тип каждого значения должен быть совместим с типом выражения.
Команду switch часто называют командой выбора. Выбор осуществляется в зависимости от целочисленного выражения. Форма команды выглядит так:
switch(ВыражениеДляСравнения)
Параметр ВыражениеДляСравнения — выражение, в результате вычисления которого получается целое число (как правило). Команда switch сравнивает результат ВыражениеДляСравнения с каждым последующим Совпадением. Если обнаруживается совпадение, то исполняется команда или набор команд, которые прописаны за данным оператором. Если совпадений не будет, то исполняется команда после ключевого слова default. Однако оператор default не является обязательным. В этом случае при отсутствии совпадений программа не выполняет никаких действий.
Каждая секция case обычно заканчивается командой break, которая передаёт управление к концу команды switch.
Рассмотрим простейший пример с месяцами. Запустим наш учебный проект и добавим код в обработчик нажатия кнопки:
int month = 3; String monthString; switch (month) < case 1: monthString = "Январь"; break; case 2: monthString = "Февраль"; break; case 3: monthString = "Март"; break; case 4: monthString = "Апрель"; break; case 5: monthString = "Май"; break; case 6: monthString = "Июнь"; break; case 7: monthString = "Июль"; break; case 8: monthString = "Август"; break; case 9: monthString = "Сентябрь"; break; case 10: monthString = "Октябрь"; break; case 11: monthString = "Ноябрь"; break; case 12: monthString = "Декабрь"; break; default: monthString = "Не знаем такого"; break; >mInfoTextView.setText(monthString);
Запустите проект и нажмите кнопку — в текстовом поле появится слово Март (любимый месяц котов).
При желании, можно переписать пример с использованием if-then-else:
int month = 3; if (month == 1) < mInfoTextView.setText("Январь"); >else if (month == 2) < mInfoTextView.setText("Февраль"); >. // и так далее
В каждом блоке case имеется оператор break, который прерывает свой блок кода. Его нужно использовать обязательно, иначе выполнение кода продолжится. Хотя иногда это и используется.
java.util.ArrayList futureMonths = new java.util.ArrayList(); int month = 8; switch (month) < case 1: futureMonths.add("January"); case 2: futureMonths.add("February"); case 3: futureMonths.add("March"); case 4: futureMonths.add("April"); case 5: futureMonths.add("May"); case 6: futureMonths.add("June"); case 7: futureMonths.add("July"); case 8: futureMonths.add("August"); case 9: futureMonths.add("September"); case 10: futureMonths.add("October"); case 11: futureMonths.add("November"); case 12: futureMonths.add("December"); break; default: break; >if (futureMonths.isEmpty()) < mInfoTextView.setText("Invalid month number"); >else < for (String monthName : futureMonths) < mInfoTextView.setText(monthName); >>
Если код в блоках case совпадает, то блоки можно объединить. Например, код для подсчёта дней в месяце:
int month = 2; int year = 2012; int numDays = 0; switch (month) < case 1: case 3: case 5: case 7: case 8: case 10: case 12: numDays = 31; break; case 4: case 6: case 9: case 11: numDays = 30; break; case 2: if (((year % 4 == 0) && !(year % 100 == 0)) || (year % 400 == 0)) numDays = 29; else numDays = 28; break; default: mInfoTextView.setText("Несуществующий месяц"); break; >mInfoTextView.setText("Число дней if.php">if мы рассматривали пример с временами года. Перепишем его с использованием оператора switch: int month = 3; String season; switch (month) < case 12: case 1: case 2: season = "Зимушка-зима"; break; case 3: case 4: case 5: season = "Весна"; break; case 6: case 7: case 8: season = "Лето"; break; case 9: case 10: case 11: season = "Осень"; break; default: season = "Вы с какой планеты?"; >mInfoTextView.setText("Мартовские песни коты поют, когда на дворе " + season);
Следующий пример случайным образом генерирует английские буквы. Программа определяет, гласные они или согласные:
Random random = new Random(); for (int i = 0; i < 100; i++) < int c = random.nextInt(26) + 'a'; mInfoTextView.setText((char)c + ", " + c + ": "); switch (c) < case 'a': case 'e': case 'i': case 'o': case 'u': mInfoTextView.setText("Гласная"); break; case 'y': case 'w': mInfoTextView.setText("Условная гласная"); break; default: mInfoTextView.setText("Согласная"); break; >>
Так как метод Random.nextInt(26) генерирует значение между 0 и 26, для получения символа нижнего регистра остаётся прибавить смещение 'a', при этом символ a автоматически преобразуется к типу int. Символы в секциях case также представляют собой целочисленные значения, используемые для сравнения.
Чтобы вывести переменную c в символьном виде, её необходимо преобразовать к типу char, иначе значение будет выведено в числовом виде.
В Java SE 7 появилась возможность использовать объект String в операторе switch. Возможно, это будет работать и на Android в будущем (Upd.: вроде уже работает):
public class StringSwitchDemo < public static int getMonthNumber(String month) < int monthNumber = 0; if (month == null) < return monthNumber; >switch (month.toLowerCase()) < case "january": monthNumber = 1; break; case "february": monthNumber = 2; break; case "march": monthNumber = 3; break; case "april": monthNumber = 4; break; case "may": monthNumber = 5; break; case "june": monthNumber = 6; break; case "july": monthNumber = 7; break; case "august": monthNumber = 8; break; case "september": monthNumber = 9; break; case "october": monthNumber = 10; break; case "november": monthNumber = 11; break; case "december": monthNumber = 12; break; default: monthNumber = 0; break; >return monthNumber; > public static void main(String[] args) < String month = "August"; int returnedMonthNumber = StringSwitchDemo.getMonthNumber(month); if (returnedMonthNumber == 0) < System.out.println("Invalid month"); >else < System.out.println(returnedMonthNumber); >> >
Допустимы вложенные операторы switch, но на практике я не сталкивался с таким кодом.
Запомните важные свойства оператора switch:
- Оператор switch отличается от оператора if тем, что может выполнять проверку только равенства, а оператор if может вычислять результат булева выражения любого типа.
- Две константы case в одном и том же операторе switch не могут иметь одинаковые значения
- Оператор switch эффективнее набора вложенных операторов if
Чем заменить switch java
Не могу понять людей которые статью не поняли. Всё предельно разжёвано. Просто попробуйте как оно работает и всё поймёте.
Дария Уровень 10 Expert
2 октября 2023
и тут ты понимаешь, что тебе нужен репетитор
Gregory2.0 Уровень 18
14 сентября 2023
Такой вопрос, обязательно ли в этом коде break int count = 2; int value = switch (count) < case 1 -> < //некоторые вычислительные операции. break 12; >case 2 -> < //некоторые вычислительные операции. break 32; >Или можно поступить каr здесь: int count = 2; int value = switch (count) < case 1 ->12; case 2 -> 32; case 3 -> 52; default -> 0; >;
komandor1 Уровень 26
4 сентября 2023
То ли я тупой, то ли лыжи не едут), но я не понял зачем нужны пустые кейсы, а потом перечитал раз 10 и кааак опять не понял
Dmitry Vidonov Уровень 29 Expert
14 августа 2023
Круто! Очень много интересного по свитчу
Сергей Уровень 19 Expert
30 июля 2023
подскажите, пожалуйста, не могу до конца понять чем отличается несколько if подряд от if и else if ?
Alexander Rozenberg Уровень 28
18 июля 2023
Skotique Уровень 35
27 июня 2023
классно, много нового (неожиданно)
No Name Уровень 32
11 июня 2023
+ статья в копилку
Ислам Уровень 32
31 мая 2023
Очень интересная лекция
Сообщество
JavaRush — это интерактивный онлайн-курс по изучению Java-программирования c нуля. Он содержит 1200 практических задач с проверкой решения в один клик, необходимый минимум теории по основам Java и мотивирующие фишки, которые помогут пройти курс до конца: игры, опросы, интересные проекты и статьи об эффективном обучении и карьере Java‑девелопера.
Подписывайтесь
Язык интерфейса
"Программистами не рождаются" © 2023 JavaRush
Скачивайте наши приложения
"Программистами не рождаются" © 2023 JavaRush
Этот веб-сайт использует данные cookie, чтобы настроить персонально под вас работу сервиса. Используя веб-сайт, вы даете согласие на применение данных cookie. Больше подробностей — в нашем Пользовательском соглашении.
Как красиво избавиться от switch-case посредством перечисления
Привет, Хабр! Применение switch-case в коде - давняя тема холиваров на форумах на предмет чистоты кода. Лично я склоняюсь к простому мнению: инструмент необходимо использовать по назначению.
Сегодня хотелось бы рассмотреть несколько простых кейсов, где switch-case является не лучшим выбором и предложить красивое и удобное решение проблемы.
Итак, непосредственно, кейс: от значения одной переменной зависит значение другой переменной.
Исходные данные: программа, имитирующая зоопарк. Она содержит несколько животных, представленных в виде перечисления Animal, и пару работников, описанных интерфейсом ZooWorker.
public enum Animal
public interface ZooWorker
Задача: научить работников кормить животных (по сути - реализовать интерфейс ZooWorker). Алгоритм действия очень прост - необходимо определить название корма, которым питается животное, и вывести в консоль сообщение о том, что животное покормлено и чем именно оно покормлено.
Первый вариант написан на java 11. Он является самым громоздким и выглядит следующим образом:
public class Java11Worker implements ZooWorker < @Override public void feed(Animal animal) < String foodName; switch (animal) < case OWL: foodName = "Mouse"; break; case HIPPO: foodName = "Grass"; break; case PENGUIN: foodName = "Fish"; break; case MONKEY: foodName = "Banana"; break; default: throw new IllegalArgumentException("Unknown animal!"); >System.out.printf("%s eat: %s%n", animal, foodName); > >
Данное решение имеет ряд проблем:
- В случае добавления животного в перечисление, требуется дописать и вышеуказанный код.
- Разработчику никто не напомнит, что это нужно сделать. Т.е., если зоопарк разрастётся до сотен тысяч строк, вполне можно забыть, что при добавлении животного в перечисление необходимо еще и дописать код. В конце концов, это приведет к ошибке (и хорошо, если определено поведение default, в этом случае, по крайней мере, есть возможность быстро определить проблемное место).
- При большом количестве животных switch-case сильно разрастётся.
- Ну, и известная проблема switch-case в java 11 – бесконечный break, который легко пропустить.
Существует возможность немного отрефакторить вышеописанный пример и избавиться от проблемы №4 следующим образом:
public class Java11Worker implements ZooWorker < @Override public void feed(Animal animal) < String foodName = getFoodName(animal); System.out.printf("%s eat: %s%n", animal, foodName); >private String getFoodName(Animal animal) < switch (animal) < case OWL: return "Mouse"; case HIPPO: return "Grass"; case PENGUIN: return "Fish"; case MONKEY: return "Banana"; default: throw new IllegalArgumentException("Unknown animal!"); >> >
Выглядит лучше, однако, другие проблемы остаются.
Начиная с java 14 и выше появилась возможность использовать более удобный формат switch-case. Представленное выше решение в новом формате будет выглядеть следующим образом:
public class Java17Worker implements ZooWorker < @Override public void feed(Animal animal, int animalCount) < String foodName = switch (animal) < case OWL ->"Mouse"; case HIPPO -> "Grass"; case PENGUIN -> "Fish"; case MONKEY -> "Banana"; >; System.out.printf("%s eat: %s%n", animal, foodName); > >
Помимо избавления от break, решилась проблема №2: если разработчик добавит в перечисление животное, но не определит необходимое поведение в switch-case, код просто не скомпилируется. Уже лучше, однако, третья и первая проблемы все ещё остаются.
В последнем решении перенесём зависимость переменных непосредственно в перечисление. Для этого немного изменим его:
public enum Animal < HIPPO("Grass"), PENGUIN("Fish"), MONKEY("Banana"), OWL("Mouse"); @Getter private final String foodName; Animal(String foodName) < this.foodName = foodName; >>
Теперь можно реализовать работника всего в одну строку:
public class EasyWorker implements ZooWorker < @Override public void feed(Animal animal) < System.out.printf("%s eat: %s%n", animal, animal.getFoodName()); >>
В представленном решении, при добавлении элемента в перечисление, нет необходимости дописывать код, и разработчик точно не забудет нигде ничего дописать. К тому же, код не будет превращаться в лапшу при увеличении количества элементов в перечислении.
Попробуем немного расширить и усложнить наш кейс: теперь от значения одной переменной зависит не только значение другой, но и последующий алгоритм действий.
Задача остается той же - научить работников кормить животных. Однако, теперь для того, чтобы покормить животное, необходимо не просто определить требуемый корм, но и рассчитать его объем. Для этого изменим интерфейс ZooWorker:
public interface ZooWorker
Для большей наглядности представим, что расчёт корма не везде производится простым умножением на коэффициент, а используется некая формула:
- Для бегемотов: [количество бегемотов^2]
- Для филинов: [количество филинов * 3]
- Для пингвинов: [(количество пингвинов ^ 3)/2]
- Для обезьян: [количество обезьян * 10]
Ниже представлены решения по уже используемым шаблонам:
Решение switch-case на java 11
public class Java11Worker implements ZooWorker < @Override public void feed(Animal animal, int animalCount) < String foodName; int foodQuantity; switch (animal) < case OWL: foodName = "Mouse"; foodQuantity = animalCount * 3; break; case HIPPO: foodName = "Grass"; foodQuantity = (int) Math.pow(animalCount, 2); break; case MONKEY: foodName = "Banana"; foodQuantity = animalCount * 10; break; case PENGUIN: foodName = "Fish"; foodQuantity = (int) (Math.pow(animalCount, 3)/2); break; default: throw new IllegalArgumentException("Unknown animal!"); >System.out.printf("%s eat: %d %s", animal, foodQuantity, foodName); > >
Немного переработанный код будет выглядеть следующим образом:
public class Java11Worker implements ZooWorker < @Override public void feed(Animal animal, int animalCount) < String foodName = getFoodName(animal); int foodQuantity = getfoodQuantity(animal, animalCount); System.out.printf("%s eat: %d %s", animal, foodQuantity, foodName); >private String getFoodName(Animal animal) < switch (animal) < case OWL: return "Mouse"; case HIPPO: return "Grass"; case MONKEY: return "Banana"; case PENGUIN: return "Fish"; default: throw new IllegalArgumentException("Unknown animal!"); >> private int getfoodQuantity(Animal animal, int animalCount) < switch (animal) < case OWL: return animalCount * 3; case HIPPO: return (int) Math.pow(animalCount, 2); case MONKEY: return animalCount * 10; case PENGUIN: return (int) (Math.pow(animalCount, 3)/2); default: throw new IllegalArgumentException("Unknown animal!"); >> >
Решение switch-case на java 17
public class Java17Worker implements ZooWorker < @Override public void feed(Animal animal, int animalCount) < String foodName = switch (animal) < case OWL ->"Mouse"; case HIPPO -> "Grass"; case PENGUIN -> "Fish"; case MONKEY -> "Banana"; >; int foodQuantity = switch (animal) < case OWL ->animalCount * 3; case HIPPO -> (int) Math.pow(animalCount, 2); case PENGUIN -> (int) (Math.pow(animalCount, 3) / 2); case MONKEY -> animalCount * 10; >; System.out.printf("%s eat: %d %s", animal, foodQuantity, foodName); > >
Для решения через enum требуется доработать перечисление:
public enum Animal < HIPPO("Grass", animalCount ->(int) Math.pow(animalCount, 2)), PENGUIN("Fish", animalCount -> (int) (Math.pow(animalCount, 3) / 2)), MONKEY("Banana", animalCount -> animalCount * 10), OWL("Mouse", animalCount -> animalCount * 3); @Getter private final String foodName; @Getter private final IntFunction foodCalculation; Animal(String foodName, IntFunction foodCalculation) < this.foodName = foodName; this.foodCalculation = foodCalculation; >>
И, собственно, сам работник:
public class EasyWorker implements ZooWorker < @Override public void feed(Animal animal, int animalCount) < System.out.printf("%s eat: %d %s", animal, animal.getFoodCalculation().apply(animalCount), animal.getFoodName() ); >>
Перейдем к заключительному примеру. Предположим, расчёт корма представляет собой сложную логику, которую не получится передать в качестве лямбды.
В этом случае для каждого животного создадим отдельного сотрудника, который будет кормить только его.
public class HippoWorker implements ZooWorker < private final String foodName; public HippoWorker(String foodName) < this.foodName = foodName; >@Override public void feed(int animalCount) < //Сложная логика int foodQuantity = (int) Math.pow(animalCount, 2); System.out.printf("Hippo eat: %d %s", foodQuantity, foodName); >>
public class MonkeyWorker implements ZooWorker < private final String foodName; public MonkeyWorker(String foodName) < this.foodName = foodName; >@Override public void feed(int animalCount) < //Сложная логика int foodQuantity = animalCount * 10; System.out.printf("Monkey eat: %d %s", foodQuantity, foodName); >>
public class OwlWorker implements ZooWorker < private final String foodName; public OwlWorker(String foodName) < this.foodName = foodName; >@Override public void feed(int animalCount) < //Сложная логика int foodQuantity = animalCount * 3; System.out.printf("Owl eat: %d %s", foodQuantity, foodName); >>
public class PenguinWorker implements ZooWorker < private final String foodName; public PenguinWorker(String foodName) < this.foodName = foodName; >@Override public void feed(int animalCount) < //Сложная логика int foodQuantity = (int) (Math.pow(animalCount, 3) / 2); System.out.printf("Penguin eat: %d %s", foodQuantity, foodName); >>
Представим, как решить задачу «покормить всех животных» «в лоб»: например, в вызывающем классе собираем список (множество) всех работников, и получаем возможность по очереди вызвать метод feed у элементов списка. Вышло бы что-то вроде этого:
public class Feeder < private final ListworkerList; public Feeder(List workerList) < this.workerList = workerList; >public void feedAll(int animalCount) < workerList.forEach(zooWorker ->zooWorker.feed(animalCount)); > >
Выглядит неплохо, однако, что делать, если потребуется отдельный метод для каждого животного, например, public void feedHippo(int animalCount) , или универсальный public void feedAnimal(Animal animal, int animalCount) ? На данном этапе возникнут проблемы. Решением может быть создание мапы,содержащей всех работников. Но тогда необходимо хранить ключи к ней (или хардкодить). Можно сделать ключом непосредственно значение перечисления, но все равно придется где-то собирать мапу. Другим решением может стать внедрение работников в качестве полей, но их [работников] может быть много, а feedAnimal будет опять работать на громоздком switch-case. И все эти варианты нужно поддерживать, а при добавлении нового животного придется искать по коду, где отрабатывает логика кормления.
Однако, если изменим перечисление следующим образом:
public enum Animal < HIPPO(new HippoWorker("Grass")), PENGUIN(new PenguinWorker("Fish")), MONKEY(new MonkeyWorker("Banana")), OWL(new OwlWorker("Mouse")); private final ZooWorker worker; Animal(ZooWorker worker) < this.worker = worker; >public void feed(int animalCount) < worker.feed(animalCount); >>
Все становится настолько простым:
public class Feeder < public void feedAll(int animalCount) < Arrays.stream(Animal.values()) .forEach(animal ->animal.feed(animalCount)); > public void feedHippo(int animalCount) < Animal.HIPPO.feed(animalCount); >public void feedAnimal(Animal animal, int animalCount) < animal.feed(animalCount); >>
Мы рассмотрели 3 варианта с нарастающей сложностью, где можно красиво применить перечисление вместо switch-case. Предложенные решения задач просты в реализации и более поддерживаемы и расширяемы по сравнению с решением "в лоб" с использованием switch-case.