Большинство операций в Java аналогичны тем, которые применяются в других си-подобных языках. Есть унарные операции (выполняются над одним операндом), бинарные — над двумя операндами, а также тернарные — выполняются над тремя операндами. Операндом является переменная или значение (например, число), участвующее в операции. Рассмотрим все виды операций.
Арифметические операции
+
операция сложения двух чисел, например:z=x+y
-
операция вычитания двух чисел:z=x-y
*
операция умножения двух чисел:z=x*y
/
операция деления двух чисел:z=x/y
%
получение остатка от деления двух чисел:z=x%y
++ (префиксный инкремент)
Предполагает увеличение переменной на единицу, например,z=++y
(вначале значение переменной y увеличивается на 1, а затем ее значение присваивается переменной z)++ (постфиксный инкремент)
также, увеличение переменной на единицу, например,z=y++
(вначале значение переменной y присваивается переменной z, а потом значение переменной y увеличивается на 1)-- (префиксный декремент)
уменьшение переменной на единицу, например,z=--y
(вначале значение переменной y уменьшается на 1, а потом ее значение присваивается переменной z)-- (постфиксный декремент)
z=y--
(сначала значение переменной y присваивается переменной z, а затем значение переменной y уменьшается на 1)
Примеры:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
int a1 = 3 + 4; // результат равен 7 int a2 = 10 - 7; //результат равен 3 int a3 = 10 * 5; //результат равен 50 double a4 = 14.0 / 5.0; //результат равен 2.8 double a5 = 14.0 % 5.0; //результат равен 4 int b1 = 5; int c1 = ++b1; // c1=6; b1=6 int b2 = 5; int c2 = b2++; // c2=5; b2=6 int b3 = 5; int c3 = --b3; // c3=4; b3=4 int b4 = 5; int c4 = b4--; // c4=5; b4=4 |
Операцию сложения также можно применять к строкам, в этом случае происходит конкатенация строк:
1 |
String hello = "hell to " + "world"; //результат равен "hell to world" |
Логические операции над числами
Логические операции над числами представляют поразрядные операции. В данном случае числа рассматриваются в двоичном представлении, например, 2 в двоичной системе равно 10 и имеет два разряда, число 7 — 111 и имеет три разряда.
& (логическое умножение)
Умножение производится поразрядно, и если у обоих операндов значения разрядов равно 1, то операция возвращает 1, иначе возвращается число 0. Например:
1 2 3 4 5 6 7 |
int a1 = 2; //010 int b1 = 5;//101 System.out.println(a1&b1); // результат 0 int a2 = 4; //100 int b2 = 5; //101 System.out.println(a2 & b2); // результат 4 |
- В первом случае у нас два числа 2 и 5. 2 в двоичном виде представляет число 010, а 5 — 101. Поразрядное умножение чисел (0*1, 1*0, 0*1) дает результат 000.Во втором случае у нас вместо двойки число 4, у которого в первом разряде 1, так же как и у числа 5, поэтому здесь результатом операции (1*1, 0*0, 0 *1) = 100 будет число 4 в десятичном формате.
|
(логическое сложение)Данная операция также производится по двоичным разрядам, но теперь возвращается единица, если хотя бы у одного числа в данном разряде имеется единица (операция «логическое ИЛИ»). Например:
1 2 3 4 5 6 |
int a1 = 2; //010 int b1 = 5;//101 System.out.println(a1|b1); // результат 7 - 111 int a2 = 4; //100 int b2 = 5;//101 System.out.println(a2 | b2); // результат 5 - 101 |
^
(логическое исключающее ИЛИ)
Также эту операцию называют XOR, нередко ее применяют для простого шифрования:
1 2 3 4 5 6 7 |
int number = 45; // 1001 Значение, которое надо зашифровать - в двоичной форме 101101 int key = 102; //Ключ шифрования - в двоичной системе 1100110 int encrypt = number ^ key; //Результатом будет число 1001011 или 75 System.out.println("Зашифрованное число: " +encrypt); int decrypt = encrypt ^ key; // Результатом будет исходное число 45 System.out.println("Расшифрованное число: " + decrypt); |
- Здесь также производятся поразрядные операции. Если у нас значения текущего разряда у обоих чисел разные, то возвращается 1, иначе возвращается 0. Например, результатом выражения 9^5 будет число 12. А чтобы расшифровать число, мы применяем обратную операцию к результату.
~
(логическое отрицание)Поразрядная операция, инвертирующая все разряды числа: если значение разряда равно 1, то оно становится равным нулю, и наоборот.
12int a = 56;System.out.println(~a);Операции сдвига
Операции сдвига также производятся над разрядами чисел. Сдвиг может происходить вправо и влево.
a<<b
— сдвигает число a влево на b разрядов. Например, выражение4<<1
сдвигает число 4 (которое в двоичном представлении 100) на один разряд влево, в результате получается число 1000 или число 8 в десятичном представлении.a>>b
— смещает число a вправо на b разрядов. Например,16>>1
сдвигает число 16 (которое в двоичной системе 10000) на один разряд вправо, то есть в итоге получается 1000 или число 8 в десятичном представлении.a>>>b
— в отличие от предыдущих типов сдвигов данная операция представляет беззнаковый сдвиг — сдвигает число a вправо на b разрядов. Например, выражение-8>>>2
будет равно 1073741822.
Таким образом, если исходное число, которое надо сдвинуть в ту или другую строну, делится на два, то фактически получается умножение или деление на два. Поэтому подобную операцию можно использовать вместо непосредственного умножения или деления на два, так как операция сдвига на аппаратном уровне менее дорогостоящая операция в отличие от операции деления или умножения.
Операции сравнения
В операциях сравнения сравниваются два операнда, и возвращается значение типа
boolean
—true
, если выражение верно, иfalse
, если выражение неверно.==
данная операция сравнивает два операнда на равенство:c=a==b;
c равно
true
, если a равно b, иначе c будет равноfalse
!=
c=a!=b;
(c равноtrue
, если a не равно b, иначе c будет равноfalse
)<
c=a<b;
(c равноtrue
, если a меньше b, иначе c будет равноfalse
)>
c=a>b;
(c равноtrue
, если a больше b, иначе c будет равноfalse
)<=
c=a<=b;
(c равноtrue
, если a меньше или равно b, иначе c будет равноfalse
)>=
c=a>=b;
(c равноtrue
, если a больше или равно b, иначе c будет равноfalse
)
Кроме собственно операций сравнения в Java также определены логические операторы, которые возвращают значение типа
boolean
. Выше мы рассматривали поразрядные операции над числами. Теперь же рассмотрим эти же операторы при операциях над булевыми значениями:|
c=a|b;
(c равноtrue
, если либо a, либо b (либо и a, и b) равныtrue
, иначе c будет равноfalse
)&
c=a&b;
(c равноtrue
, если и a, и b равныtrue
, иначе c будет равноfalse
)!
c!=b;
(c равноtrue
, если b равноfalse
, иначе c будет равноfalse
)^
c=a^b;
(c равноtrue
, если либо a, либо b (но не одновременно) равныtrue
, иначе c будет равноfalse
)||
c=a||b;
(c равноtrue
, если либо a, либо b (либо и a, и b) равныtrue
, иначе c будет равноfalse
)&&
c=a&&b;
(c равноtrue
, если и a, и b равныtrue
, иначе c будет равноfalse
)
Здесь у нас две пары операций
|
и||
(а также&
и&&
) выполняют похожие действия, однако же они не равнозначны.Выражение
c=a|b;
будет вычислять сначала оба значения — a и b и на их основе выводить результат.В выражении же
c=a||b;
вначале будет вычисляться значение a, и если оно равноtrue
, то вычисление значения b уже смысла не имеет, так как у нас в любом случае уже c будет равноtrue
. Значение b будет вычисляться только в том случае, если a равноfalse
То же самое касается пары операций
&/&&
. В выраженииc=a&b;
будут вычисляться оба значения — a и b.В выражении же
c=a&&b;
сначала будет вычисляться значение a, и если оно равноfalse
, то вычисление значения b уже не имеет смысла, так как значение c в любом случае равноfalse
. Значение b будет вычисляться только в том случае, если a равноtrue
Таким образом, операции
||
и&&
более удобны в вычислениях, позволяя сократить время на вычисление значения выражения и тем самым повышая производительность. А операции|
и&
больше подходят для выполнения поразрядных операций над числами.Примеры:
123456boolean a1 = (5 > 6) || (4 < 6); // 5 > 6 - false, 4 < 6 - true, поэтому возвращается trueboolean a2 = (5 > 6) || (4 > 6); // 5 > 6 - false, 4 > 6 - false, поэтому возвращается falseboolean a3 = (5 > 6) && (4 < 6); // 5 > 6 - false, 4 < 6 - true, поэтому возвращается falseboolean a4 = (50 > 6) && (4 / 2 < 3); // 50 > 6 - true, 4/2 < 3 - true, поэтому возвращается trueboolean a5 = (5 > 6) ^ (4 < 6); // 5 > 6 - false, 4 < 6 - true, поэтому возвращается trueboolean a6 = (50 > 6) ^ (4 / 2 < 3); // 50 > 6 - true, 4/2 < 3 - true, поэтому возвращается falseОперации присваивания
В завершении рассмотрим операции присваивания, которые в основном представляют комбинацию простого присваивания с другими операциями:
=
просто приравнивает одно значение другому:c=b;
+=
c+=b;
(переменной c присваивается результат сложения c и b)-=
c-=b;
(переменной c присваивается результат вычитания b из c)*=
c*=b;
(переменной c присваивается результат произведения c и b)/=
c/=b;
(переменной c присваивается результат деления c на b)%=
c%=b;
(переменной c присваивается остаток от деления c на b)&=
c&=b;
(переменной c присваивается значение c&b)|=
c|=b;
(переменной c присваивается значение c|b)^=
c^=b;
(переменной c присваивается значение c^b)<<=
c<<=b;
(переменной c присваивается значение c<<b)>>=
c>>=b;
(переменной c присваивается значение c>>b)>>>=
c>>>=b;
(переменной c присваивается значение c>>>b)
Приоритет операций
При работе с операциями важно понимать их приоритет, который можно описать следующей таблицей:
expr++ expr— ++expr —expr +expr -expr ~ ! * / % + — << >> >>> < > <= >= instanceof == != & ^ | && || ? : (тернарный оператор) = += -= *= /= %= &= ^= |= <<= >>= >>>= (операторы присваивания) Чем выше оператор в этой таблице, тем больше его приоритет. При этом скобки повышают приоритет операции, используемой в выражении. Рассмотрим небольшой пример:
1 2 3 |
int x = 4; int y = 5; int z = 100 + 10 * -20 / ++x * (y-1); |
Как в этом случае будет выполняться выражение, результат которого приравнивается переменной z:
10*-20
(результат -200)++x
(результат 5)10 * -20 /++x
(результат -200 / 5 = -40)(y -1)
(результат 5 — 1 = 4)10 * -20 /++x * (y -1)
(результат -40 * 4 = -160)100 + 10 * -20 /++x * (y -1)
(результат 100 + -160 = -60)