运算符

算术运算符

整数类型和整数类型运算只能得到整数类型

  1. System.out.println(10 / 3);//3
  2. System.out.println(10.0 / 3);//3.3333333333333335

% 取模 取余
前面的数比后面的数小 那么就返回前面的值

  1. System.out.println(10 % 5); // 0
  2. System.out.println(5 % 10); // 5 前面的数比后面的数小 那么就返回前面的值

自增 自减

作为独立语句使用, i++和++i完全等价于i=i+1

  1. int i = 10;
  2. i++;// i = i + 1;
  3. ++i; // i = i + 1;
  4. System.out.println("i=" + i);//11

表达式使用
++i 先自增后赋值
i++ 先赋值后自增

  1. int j = 8;
  2. int k = ++j; //j= j+1;k=j
  3. System.out.println("k=" + k + "j=" + j) ;//9 9
  1. int l = 8;
  2. int n = j++; //k=j; j = j+1
  3. System.out.println("n=" + n + "j=" + j); //8 9

注意事项:只有变量才能使用自增、自减运算符,常量不可发生改变,所以不能用

关系运算符

关系运算符返回boolean类型

  • >
  • <
  • >=
  • <=
  • ==
  • !=
    1. public class OperatorDemo2 {
    2. public static void main(String[] args) {
    3. int a = 10;
    4. int b = 5;
    5. System.out.println(a > b);
    6. System.out.println(a < b);
    7. System.out.println(a >= b);
    8. System.out.println(a <= b);
    9. System.out.println(a == b);
    10. System.out.println(a != b);
    11. }
    12. }

逻辑运算符

  • &
  • |
  • !
  1. public class OperatorDemo3 {
  2. public static void main(String[] args) {
  3. System.out.println('&');
  4. System.out.println(true & false); //false
  5. System.out.println(false & true); //false
  6. System.out.println(true & true); //true
  7. System.out.println(false & false); //false
  8. System.out.println('|');
  9. System.out.println(true | false); //true
  10. System.out.println(false | true); //true
  11. System.out.println(true | true); //true
  12. System.out.println(false | false); //false
  13. System.out.println('!');
  14. System.out.println(!false); //true
  15. System.out.println(!true); //false
  16. }
  17. }

&& || 和& |最终结果是一样的 可以提高性能

造成短路,当逻辑运算符左边已经决定整个结果时,右边不执行

  1. int a = 10;
  2. int b = 5;
  3. int c = 8;
  4. System.out.println((a < b) & (a++ > c));
  5. System.out.println(a); // 11
  6. a = a - 1;
  7. System.out.println((a < b) && (a++ > c));
  8. System.out.println(a); //10

注意事项:

  • 逻辑运算符只能用于boolean
  • 与、或需要左右各自一个boolean值,但是取反只有唯一一个boolean值即可
  • 与、或两种运算符,如果多个条件可以连续写

赋值运算符

赋值运算符=

扩展赋值运算符

  • -=
  • +=
  • *=
  • /=

    1. public class OperatorDemo4 {
    2. public static void main(String[] args) {
    3. // 把10赋值给a变量
    4. int a = 10;
    5. a += 10;// a = a + 10 左边和右边进行运算之后赋值给左边
    6. System.out.println(a);
    7. }
    8. }

    注意事项:

  • 只有变量才能使用赋值运算符,常量不能进行赋值

  • 复合运算符其中隐藏了一个强制类型转换

位运算

位运算效率高

  • <<左移,相当于乘2,左移n位相当于乘以2的n次方
  • >>右移,相当于除以2 ,右移n位相当于除以2的n次方

面试题:2*8=16,怎样运算最快

答:用位运算最快
0000 0001 1
0000 0010 2
0000 0100 4
0000 1000 8
0001 0000 16
所以把2左移3,就可以得到16

  1. System.out.printlin(2<<3);//输出16

三元运算符

a ? b : c;

a为真返回b否则返回c

  1. int x,y,z;
  2. x = 6,y = 2;
  3. z = x>y ? x-y : x+y;

在这里要计算 z 的值,首先要判断x>y表达的值,如果为 true,z 的值为x-y;否则 z 的值为 x+y。很明显 x>y 表达式结果为 true,所以 z 的值为 4

字符串连接符 +

+一边出现字符串类型时,运算返回的是字符串类型。运算符优先级不变,还是从左到右

  1. System.out.printlin(""+1+2);//12 拼接
  2. System.out.printlin(1+2+"");//3,先进行加法运算,再与字符串连接

编译器的2点优化

对于byte/short/char三种类型来说,如果右侧赋值的数值没有超过范围,那么javac编译器将会自动隐含地为我们补上一个(byte)(short)(char)。
1. 如果没有超过左侧的范围,编译器补上强转。
2. 如果右侧超过了左侧范围,那么直接编译器报错。

  1. public class Demo12Notice {
  2. public static void main(String[] args) {
  3. // 右侧确实是一个int数字,但是没有超过左侧的范围,就是正确的。
  4. // int --> byte,不是自动类型转换
  5. byte num1 = /*(byte)*/ 30; // 右侧没有超过左侧的范围
  6. System.out.println(num1); // 30
  7. // byte num2 = 128; // 右侧超过了左侧的范围
  8. // int --> char,没有超过范围
  9. // 编译器将会自动补上一个隐含的(char)
  10. char zifu = /*(char)*/ 65;
  11. System.out.println(zifu); // A
  12. }
  13. }

在给变量进行赋值的时候,如果右侧的表达式当中全都是常量,没有任何变量,那么编译器javac将会直接将若干个常量表达式计算得到结果。
short result = 5 + 8;// 等号右边全都是常量,没有任何变量参与运算,编译之后,得到的.class字节码文件当中相当于【直接就是】:
short result = 13;,右侧的常量结果数值,没有超过左侧范围,所以正确。这称为“编译器的常量优化”。
但是注意:一旦表达式当中有变量参与,那么就不能进行这种优化了。

  1. public class Demo13Notice {
  2. public static void main(String[] args) {
  3. short num1 = 10; // 正确写法,右侧没有超过左侧的范围,
  4. short a = 5;
  5. short b = 8;
  6. // short + short --> int + int --> int
  7. // short result = a + b; // 错误写法!左侧需要是int类型
  8. // 右侧不用变量,而是采用常量,而且只有两个常量,没有别人
  9. short result = 5 + 8;
  10. System.out.println(result);
  11. short result2 = 5 + a + 8; // 18
  12. }
  13. }

进制转换

二进制转十进制

规制

从右到左:每个数乘以2的(位数-1)次方,然后相加,小数点后则是从左往右


示例

1011=12(1-1)次方+12(2-1)次方+02(3-1)次方+12(4-1)=11

八进制转换成十进制

规制

从右到左:每个数乘以8的(位数-1)次方,然后相加,小数点后则是从左往右


示例

1011=18(1-1)次方+18(2-1)次方+08(3-1)次方+18(4-1)次方=521

十六进制转换成十进制

规制

从右到左:每个数乘以16的(位数-1)次方,然后相加,小数点后则是从左往右


示例

0x23A = 10 16^0 + 3 16 ^ 1 + 2 * 16^2 = 10 + 48 + 512 = 570


十进制转换成二进制

规制

将该数不断除以2,直到商为0为止,然后将每步得到的余数倒过来,就是对应的二进制


示例

34= 0B00100010
第3章:运算符 - 图1

十进制转换成八进制

规制

将该数不断除以8,直到商为0为止,然后将每步得到的余数倒过来,就是对应的八进制


示例

请将131转成八进制=> 0203
第3章:运算符 - 图2

十进制转换成十六进制

规制

将该数不断除以16,直到商为0为止,然后将每步得到的余数倒过来,就是对应的八进制


示例

237转成十六进制=> 0xED
第3章:运算符 - 图3

二进制转换成八进制

规则

从低位开始,将二进制数每三位一组,转成对应的八进制数即可


示例(二进制先转十进制)

ob11(3)010(2)101(5) => 0325

二进制转换成十六进制

规则

从低位开始,将二进制数每四位一组,转成对应的十六进制数即可

示例(二进制先转十进制)

ob1101(D)0101(5) = 0xD5

八进制转换成二进制

规则

将八进制数每1位,转成对应的一个3位的二进制数即可

示例

02(010)3(011)7(111) = 0b10011111


十六进制转换成二进制

规则

将十六进制数每1位,转成对应的4位的一个二进制数即可

示例

0x2(0010)3(0011)B(1011) = 0b001000111011

进制及运算

二进制在运算中的说明

  • 二进制是逢2进位的进位制,0、1是基本算符
  • 现代的电子计算机技术全部采用的是二进制,因为它只使用0、1两个数字符号,非常简单方便,易于用电子方式实现,计算机内部处理的信息,都是采用二进制数来表示,二进制数用0、1两个数据及其组合来表示任何数,进位规则是逢2进1,数字1在不同的位上代表不同的值,按从右至左的次序,这个值以二倍递增

原码、反码、补码(重点 难点)

  • 二进制的最高位是符号位:0表示正数,1表示负数
  • 正数的原码,反码,补码都是一样(三码合一)
  • 负数的反码=它的原码符号位不变,其他位取反(0->1,1->0)
  • 负数的补码=它的反码+1,负数的反码=负数的补码-1
  • 0的反码,补码都是0
  • java没有无符号数,也就是:java中的数都是有符号的
  • 在计算机运算的时候,都是以补码的方式来运算的
  • 当我们看运算结果的时候,要看他的原码