В некоторых ситуациях возникает потребность досрочно перейти к выполнению следующей итерации, проигнорировав часть операторов тела цикла, еще не выполненных в текущей итерации. Для этой цели в Java предусмотрен оператор continue. Ниже приведен пример, в котором оператор continue используется для того, чтобы в каждой строке печатались два числа.
class ContinueDemo {
public static void main(String args[]) {
for (int i=0; i < 10; i++) {
System.out.print(i + " ");
if (i % 2 == 0) continue;
System.out.println("");
} } }
Если индекс четный, цикл продолжается без вывода символа новой строки. Результат выполнения этой программы таков:
0 1
2 3
4 5
6 7
8 9
Как и в случае оператора break, в операторе continue можно задавать метку, указывающую, в каком из вложенных циклов вы хотите досрочно прекратить выполнение текущей итерации. Для иллюстрации служит программа, использующая оператор continue с меткой для вывода треугольной таблицы умножения для чисел от 0 до 9:
class ContinueLabel {
public static void main(String args[]) {
outer: for (int i=0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
if (j > i) { System.out.println(""); continue outer;
}
System.out.print(" " + (i * j));
} } } }
Оператор continue в этой программе приводит к завершению внутреннего цикла со счетчиком j и переходу к очередной итерации внешнего цикла со счетчиком i. В процессе работы эта программа выводит следующие строки:
0
0 1
0 2 4
0 3 6 9
0 4 8 12 16
0 5 10 15 20 25
0 6 12 18 24 30 36
0 7 14 21 28 35 42 49
0 8 16 24 32 40 48 56 64
0 9 18 27 36 45 54 63 72 81
В стандартной библиотеке языка Java содержатся два класса для произведения базовых математических операций, таких как возведение в степень, взятие логарифма, синуса, косинуса и так далее. Эти классы отличаются между собой различной точностью представления чисел на разных архитектурах процессора. Это классы Math и StrictMath
При использовании StrictMath получаем абсолютно одинаковый результат вычислений не зависимо от процессора, который установлен у пользователя программы. Это потому, что эта функция задумывалась создателями языка как базовая для всех примитивных типов данных и манипуляций с ними. Но как оказалось это не такая простая задача и обеспечение одинаковых результатов на различных платформах значительно уменьшают быстродействие. Большинство задач просто не требуют такой точности в вычислениях, для них гораздо важнее скорость этих вычислений. Это привело к разделению математической части библиотеки на быструю и выдающую одинаковый результат на разных процессорах.
Таким образом, если в решении вашей задачи важнее скорость — используйте класс Math, если же вам необходимо одинаковая работа (с точностью до бита) с примитивными типами данных, то ваш выбор — StrictMath. Константы и методы у них одинаковы, и более того некоторые методы класса Math просто вызывают аналогичные методы класса StrictMath.
Далее рассмотрим класс Math, содержащий различные математически функции. Рассмотрим некоторые из них:
арифметические
Math.abs(n)
возвращает модуль числа n.
Math.sqrt(n)
возвращает квадратный корень из n
Math.cbrt(n)
возвращает кубический корень аргумента
Math.pow(n,b)
возвращает значение степенной функции n в степени b (n и b могут быть вещественными).
Math.log(n)
возвращает значение натурального логарифма числа n
Math.log10(n)
возвращает значение десятичного логарифма числа n.
Math.signum(n)
возвращает 1.0 если число больше 0 и -1.0 если число меньше нуля и ноль, если аргумент равен нулю;
Math.hypot(x,y)
возвращает квадратный корень из суммы аргументов: sqrt(x2+y2);
Math.max(n1,n2)
возвращает большее из двух чисел
Math.min(n1,n2)
возвращает меньшее из двух чисел;
округление
Math.round(n)
обычное округление
Math.ceil(n)
округляет значение в большую сторону
Math. floor(n)
округляет в меньшую сторону;
тригометрические
Math.cos(n), Math.sin(n), Math.tan(n)
тригонометрические функции sin, cos и tg от аргумента n, указанного в радианах.
Math.acos(n), Math.asin(n), Math.atan(n)
обратные тригонометрические функции, возвращают угол в радианах
Подведя итог можно сказать, что если добавлять к классу, интерфейсу и методам ключевое слово strictfp, то можем быть уверены, что на всех платформах при работе с числами мы получим одинаковый результат.
Все перечисленные функции принимают вещественные аргументы, а тип возвращаемого значения зависит от типа аргумента и от самой функции.
Кроме функций в рассматриваемом классе имеются две часто используемых константы:
Math.PI
число «пи», с точностью в 15 десятичных знаков
Math.E
число Неппера (основание экспоненциальной функции), с точностью в 15 десятичных знаков.
В классе Math есть полезная функция без аргументов, которая позволяет генерировать псевдослучайные значения, т.е. при каждом вызове этой функции она будет возвращать новое значение.
Math.random()
возвращает псевдослучайное вещественное число из промежутка [0;1).
Если требуется получить число из другого диапазона, то значение функции можно умножать на что-то, сдвигать и, при необходимости, приводить к целым числам.
Например:
System.out.println(Math.random()); // вещественное число из [0;1)
System.out.println(Math.random()+3); // вещественное число из [3;4)
System.out.println(Math.random()*5); // вещественное число из [0;5)
System.out.println( (int)(Math.random()*5) ); // целое число из [0;4]
System.out.println(Math.random()*5+3); // вещественное число из [3;8)
System.out.println( (int)(Math.random()*5+3)); // целое число из [3;7]
System.out.println( (int)(Math.random()*11)-5); // целое число из [-5;5]
Псевдослучайные числа имеют серьёзнейшие практические приложения и используются, например, в криптографии.
Потоки ввода/вывода и строки в Java
Для ввода данных используется класс Scanner из библиотеки пакетов Java.
Этот класс надо импортировать в той программе, где он будет использоваться. Это делается до начала открытого класса в коде программы.
В классе есть методы для чтения очередного символа заданного типа со стандартного потока ввода, а также для проверки существования такого символа.
Для работы с потоком ввода необходимо создать объект класса Scanner, при создании указав, с каким потоком ввода он будет связан. Стандартный поток ввода (клавиатура) в Java представлен объектом — System.in. А стандартный поток вывода (дисплей) — уже знакомым вам объектом System.out. Есть ещё стандартный поток для вывода ошибок — System.err.
import java.util.Scanner; // импортируем класс public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); // создаём объект класса
Scanner int i = 2; System.out.print("Введите целое число: "); if(sc.hasNextInt()) { // возвращает истину если с потока
ввода можно считать целое число i = sc.nextInt(); // считывает целое число с потока ввода и
сохраняем в переменную System.out.println(i*2); } else { System.out.println("Вы ввели не целое число"); } } }
Метод hasNextDouble(), применённый объекту класса Scanner, проверяет, можно ли считать с потока ввода вещественное число типа double, а метод nextDouble() — считывает его. Если попытаться считать значение без предварительной проверки, то во время исполнения программы можно получить ошибку (отладчик заранее такую ошибку не обнаружит). Например, попробуйте в представленной далее программе ввести какое-то вещественное число:
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); double i = sc.nextDouble(); // если ввести букву s, то случится ошибка во время исполнения System.out.println(i/3); } }
Имеется также метод nextLine(), позволяющий считывать целую последовательность символов, т.е. строку, а, значит, полученное через этот метод значение нужно сохранять в объекте класса String. В следующем примере создаётся два таких объекта, потом в них поочередно записывается ввод пользователя, а далее на экран выводится одна строка, полученная объединением введённых последовательностей символов.
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String s1, s2; s1 = sc.nextLine(); s2 = sc.nextLine(); System.out.println(s1 + s2); } }
Существует и метод hasNext(), проверяющий остались ли в потоке ввода какие-то символы.
В классе String существует масса полезных методов, которые можно применять к строкам (перед именем метода будем указывать тип того значения, которое он возвращает):
int length() — возвращает длину строки (количество символов в ней);
boolean isEmpty() — проверяет, пустая ли строка;
String replace(a, b) — возвращает строку, где символ a (литерал или переменная типа char) заменён на символ b;
String toLowerCase() — возвращает строку, где все символы исходной строки преобразованы к строчным;
String toUpperCase() — возвращает строку, где все символы исходной строки преобразованы к прописным;
boolean equals(s) — возвращает истинну, если строка к которой применён метод, совпадает со строкой s указанной в аргументе метода (с помощью оператора == строки сравнивать нельзя, как и любые другие объекты);
int indexOf(ch) — возвращает индекс символа ch в строке (индекс это порядковый номер символа, но нумероваться символы начинают с нуля). Если символ совсем не будет найден, то возвратит -1. Если символ встречается в строке нескольо раз, то вовзвратит индекс его первого вхождения.
int lastIndexOf(ch) — аналогичен предыдущему методу, но возвращает индекс последнего вхождения, если смивол встретился в строке несколько раз.
int indexOf(ch,n) — возвращает индекс символа ch в строке, но начинает проверку с индекса n (индекс это порядковый номер символа, но нумероваться символы начинают с нуля).
char charAt(n) — возвращает код символа, находящегося в строке под индексом n (индекс это порядковый номер символа, но нумероваться символы начинают с нуля).
public class Main { public static void main(String[] args) { String s1 = "firefox"; System.out.println(s1.toUpperCase()); // выведет «FIREFOX» String s2 = s1.replace('o', 'a'); System.out.println(s2); // выведет «firefax» System.out.println(s2.charAt(1)); // выведет «i» int i; i = s1.length(); System.out.println(i); // выведет 7 i = s1.indexOf('f'); System.out.println(i); // выведет 0 i = s1.indexOf('r'); System.out.println(i); // выведет 2 i = s1.lastIndexOf('f'); System.out.println(i); // выведет 4 i = s1.indexOf('t'); System.out.println(i); // выведет -1 i = s1.indexOf('r',3); System.out.println(i); // выведет -1 } }
Пример программы, которая выведет на экран индексы всех пробелов в строке, введенноё пользователем с клавиатуры:
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String s = sc.nextLine(); for(int i=0; i < s.length(); i++) { if(s.charAt(i) == ' ') { System.out.println(i); } } } }