GrabDuck

Операции языка Java

:

Последнее обновление: 30.11.2015

Большинство операций в 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)

Примеры:

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

Операцию сложения также можно применять к строкам, в этом случае происходит конкатенация строк:

String hello = "hell to " + "world"; //результат равен "hell to world"

Логические операции над числами

Логические операции над числами представляют поразрядные операции. В данном случае числа рассматриваются в двоичном представлении, например, 2 в двоичной системе равно 10 и имеет два разряда, число 7 - 111 и имеет три разряда.

  • & (логическое умножение)

    Умножение производится поразрядно, и если у обоих операндов значения разрядов равно 1, то операция возвращает 1, иначе возвращается число 0. Например:

     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 в десятичном формате.

  • | (логическое сложение)

    Данная операция также производится по двоичным разрядам, но теперь возвращается единица, если хотя бы у одного числа в данном разряде имеется единица (операция "логическое ИЛИ"). Например:

    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, нередко ее применяют для простого шифрования:

    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, то оно становится равным нулю, и наоборот.

    int 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

Таким образом, операции || и && более удобны в вычислениях, позволяя сократить время на вычисление значения выражения и тем самым повышая производительность. А операции | и & больше подходят для выполнения поразрядных операций над числами.

Примеры:

boolean a1 = (5 > 6) || (4 < 6); // 5 > 6 - false, 4 < 6 - true, поэтому возвращается true
boolean a2 = (5 > 6) || (4 > 6); // 5 > 6 - false, 4 > 6 - false, поэтому возвращается false
boolean a3 = (5 > 6) && (4 < 6); // 5 > 6 - false, 4 < 6 - true, поэтому возвращается false
boolean a4 = (50 > 6) && (4 / 2 < 3); // 50 > 6 - true, 4/2 < 3 - true, поэтому возвращается true
boolean a5 = (5 > 6) ^ (4 < 6); // 5 > 6 - false, 4 < 6 - true, поэтому возвращается true
boolean 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

== !=

&

^

|

&&

||

? : (тернарный оператор)

= += -= *= /= %= &= ^= |= <<= >>= >>>= (операторы присваивания)

Чем выше оператор в этой таблице, тем больше его приоритет. При этом скобки повышают приоритет операции, используемой в выражении. Рассмотрим небольшой пример:

int x = 4;
int y = 5;
int z = 100 + 10 * -20 / ++x * (y-1);

Как в этом случае будет выполняться выражение, результат которого приравнивается переменной z:

  1. 10*-20 (результат -200)

  2. ++x (результат 5)

  3. 10 * -20 /++x (результат -200 / 5 = -40)

  4. (y -1) (результат 5 - 1 = 4)

  5. 10 * -20 /++x * (y -1) (результат -40 * 4 = -160)

  6. 100 + 10 * -20 /++x * (y -1) (результат 100 + -160 = -60)