运算符
算术运算符
整数类型和整数类型运算只能得到整数类型
System.out.println(10 / 3);//3
System.out.println(10.0 / 3);//3.3333333333333335
% 取模 取余
前面的数比后面的数小 那么就返回前面的值
System.out.println(10 % 5); // 0
System.out.println(5 % 10); // 5 前面的数比后面的数小 那么就返回前面的值
自增 自减
作为独立语句使用, i++和++i完全等价于i=i+1
int i = 10;
i++;// i = i + 1;
++i; // i = i + 1;
System.out.println("i=" + i);//11
表达式使用
++i
先自增后赋值
i++
先赋值后自增
int j = 8;
int k = ++j; //j= j+1;k=j
System.out.println("k=" + k + "j=" + j) ;//9 9
int l = 8;
int n = j++; //k=j; j = j+1
System.out.println("n=" + n + "j=" + j); //8 9
注意事项:只有变量
才能使用自增、自减运算符
,常量不可发生改变,所以不能用
关系运算符
关系运算符返回boolean类型
>
<
>=
<=
==
!=
public class OperatorDemo2 {
public static void main(String[] args) {
int a = 10;
int b = 5;
System.out.println(a > b);
System.out.println(a < b);
System.out.println(a >= b);
System.out.println(a <= b);
System.out.println(a == b);
System.out.println(a != b);
}
}
逻辑运算符
&
与|
或!
非
public class OperatorDemo3 {
public static void main(String[] args) {
System.out.println('&');
System.out.println(true & false); //false
System.out.println(false & true); //false
System.out.println(true & true); //true
System.out.println(false & false); //false
System.out.println('|');
System.out.println(true | false); //true
System.out.println(false | true); //true
System.out.println(true | true); //true
System.out.println(false | false); //false
System.out.println('!');
System.out.println(!false); //true
System.out.println(!true); //false
}
}
&& || 和& |最终结果是一样的 可以提高性能
造成短路,当逻辑运算符左边已经决定整个结果时,右边不执行
int a = 10;
int b = 5;
int c = 8;
System.out.println((a < b) & (a++ > c));
System.out.println(a); // 11
a = a - 1;
System.out.println((a < b) && (a++ > c));
System.out.println(a); //10
注意事项:
- 逻辑运算符只能用于
boolean
值 - 与、或需要左右各自一个boolean值,但是取反只有唯一一个boolean值即可
- 与、或两种运算符,如果多个条件可以连续写
赋值运算符
赋值运算符=
扩展赋值运算符
-=
+=
*=
/=
public class OperatorDemo4 {
public static void main(String[] args) {
// 把10赋值给a变量
int a = 10;
a += 10;// a = a + 10 左边和右边进行运算之后赋值给左边
System.out.println(a);
}
}
注意事项:
只有变量才能使用赋值运算符,常量不能进行赋值
- 复合运算符其中隐藏了一个强制类型转换
位运算
位运算效率高
<<
左移,相当于乘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
System.out.printlin(2<<3);//输出16
三元运算符
a ? b : c;
当a
为真返回b
否则返回c
int x,y,z;
x = 6,y = 2;
z = x>y ? x-y : x+y;
在这里要计算 z 的值,首先要判断
x>y
表达的值,如果为 true,z 的值为x-y
;否则 z 的值为 x+y。很明显 x>y 表达式结果为 true,所以 z 的值为 4
字符串连接符 +
当+
一边出现字符串类型时,运算返回的是字符串类型
。运算符优先级不变,还是从左到右
System.out.printlin(""+1+2);//12 拼接
System.out.printlin(1+2+"");//3,先进行加法运算,再与字符串连接
编译器的2点优化
对于byte/short/char
三种类型来说,如果右侧赋值的数值没有超过范围,那么javac编译器将会自动隐含地为我们补上一个(byte)(short)(char)。
1. 如果没有超过左侧的范围,编译器补上强转。
2. 如果右侧超过了左侧范围,那么直接编译器报错。
public class Demo12Notice {
public static void main(String[] args) {
// 右侧确实是一个int数字,但是没有超过左侧的范围,就是正确的。
// int --> byte,不是自动类型转换
byte num1 = /*(byte)*/ 30; // 右侧没有超过左侧的范围
System.out.println(num1); // 30
// byte num2 = 128; // 右侧超过了左侧的范围
// int --> char,没有超过范围
// 编译器将会自动补上一个隐含的(char)
char zifu = /*(char)*/ 65;
System.out.println(zifu); // A
}
}
在给变量进行赋值的时候,如果右侧的表达式当中全都是常量,没有任何变量,那么编译器javac将会直接将若干个常量表达式计算得到结果。short result = 5 + 8;
// 等号右边全都是常量,没有任何变量参与运算,编译之后,得到的.class字节码文件当中相当于【直接就是】:short result = 13;
,右侧的常量结果数值,没有超过左侧范围,所以正确。这称为“编译器的常量优化”。
但是注意:一旦表达式当中有变量参与,那么就不能进行这种优化了。
public class Demo13Notice {
public static void main(String[] args) {
short num1 = 10; // 正确写法,右侧没有超过左侧的范围,
short a = 5;
short b = 8;
// short + short --> int + int --> int
// short result = a + b; // 错误写法!左侧需要是int类型
// 右侧不用变量,而是采用常量,而且只有两个常量,没有别人
short result = 5 + 8;
System.out.println(result);
short result2 = 5 + a + 8; // 18
}
}
进制转换
二进制转十进制
规制
从右到左:每个数乘以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
十进制转换成八进制
规制
将该数不断除以8,直到商为0为止,然后将每步得到的余数倒过来,就是对应的八进制
示例
请将131转成八进制=> 0203
十进制转换成十六进制
规制
将该数不断除以16,直到商为0为止,然后将每步得到的余数倒过来,就是对应的八进制
示例
237转成十六进制=> 0xED
二进制转换成八进制
规则
示例(二进制先转十进制)
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中的数都是有符号的
- 在计算机运算的时候,都是以补码的方式来运算的
- 当我们看运算结果的时候,要看他的原码