目录
算数运算符
在java里面有操作符的概念,其中操作符包括算数运算符,逻辑运算符,位运算符等等。
算数运算符有:
加(+),减(-),乘(),除(/),取余(%),=,-=,%=,++(自增操作符),-- (自减操作符)
运算符 | 含义 |
---|---|
+ | 求和 |
- | 相减 |
* | 乘积 |
/ | 商 |
% | 求余数(求模) |
++ | 自加一 |
– | 自减一 |
DEMO 1 :
public static void main(String[] args) {
int num1 = 13;
int num2 = 60;
System.out.println(num1 % num2); //结果13
}
当第一个操作数小于第二个操作数的时候求余数的结果就是第一个操作数
自增操作符(++)
自增操作符可以让变量自动更新(自加1),但是自增操作符又分为前缀自增和后缀自增。
-
前缀自增:将 “++”放到变量的前面,先更新更新变量之在使用变量
public static void main(String[] args) {
int num1 = 10;
System.out.println(++num1); //输出11
System.out.println(num1); //输出11
}
将 ++ 放到变量前面则先更新变量的值,然后在打印输出
2.后缀自增:将 ++ 放到变量的后面,先使用再更新变量
public static void main(String[] args) {
int num1 = 10;
System.out.println(num1++); //输出10
System.out.println(num1); //输出11
}
自减运算符( - - )和自增一样
总结:
前缀自增和后缀自增的区别:
-
前缀自增:将 ++ 放到变量的前面,先更新变量再使用变量
-
后缀自增:将 ++ 放到变量的后面,先使用变量再更新变零
前缀自减和后缀自减的区别:
-
前缀自增:将 -- 放到变量的前面,先更新变量再使用变量
-
后缀自增:将 -- 放到变量的后面,先使用变量再更新变零
关系运算符
关系运算符是用来对两个操作数进行关系比的操作符,所以它是一 个二元操作符(因为有两个操作数)用来确定两个操作数的关系(大小、等 于判断、不等于判断)就是:>、<、>=、<=、、!=。
要注意:“=”表示赋值,“==”表示判断,在 j s 里面还有“===”
二、表达式的概念 表达式就是一个或者多个操作符按照语法将一个或者多个操作数连接起来的式子,比如说“num1>num2”就是一个表达式,再比如说“num1+num2”也算一个表达式。表达式一定会返回一个值,根据返回值的类型可以将表达式分为布尔类型表达式、数值类型表达式、字符串类型表达式等等。
逻辑运算符
一、逻辑运算符 逻辑运算符是连接的是两个布尔类型表达式的操作符。逻辑运算符包括 了逻辑或运算和逻辑与运算。 1、逻辑与运算 逻辑与运算的符号“&&”,逻辑与运算特征:只有两个表达式的返回值 都是true的时候,最终的结果オ是true,否则就是false 。
DEMO1:
public static void main(String[] args) {
int num1 = 10;
int num2 = 20;
boolean flag = 9 > --num1 && ++num2 >20 ;
System.out.println(flag); //输出flag
System.out.println(num1); //输出9
System.out.println(num2); //输出20
}
发现了num2没有更新为21,原因是使用“&&”运算的时候如果第一个表达式返回的值 是false 的时候则不再执行第二个表达式了,这种现象叫做短路现象。
DEMO2 :另一种逻辑与“&”
public static void main(String[] args) {
int num1 = 10;
int num2 = 20;
boolean flag = 9 > --num1 & ++num2 >20 ;
System.out.println(flag); //输出flag
System.out.println(num1); //输出9
System.out.println(num2); //输出21
}
使用“&”可以表示逻辑与运算,但是不会出现短路现象,而且“&”还可以表示位运算(后面说)。
2、逻辑或运算 逻辑或运算符号是“||”,只要有一个表达式返回的值是true的时候最终的结果就是true,两个表达式都不成立的时候才是false
DEMO1: 第一个表达式返回值是false则第二个表达式true
public static void main(String[] args) {
int num1 = 10;
int num2 = 20;
boolean flag = 9 > --num1 || ++num2 >20 ;
System.out.println(flag); //输出true
System.out.println(num1); //输出9
System.out.println(num2); //输出21
}
DEMO2: 第一个表达式返回值是true则第二个表达式false
public static void main(String[] args) {
int num1 = 10;
int num2 = 20;
boolean flag = 12 > --num1 || ++num2 >20 ;
System.out.println(flag); //输出true
System.out.println(num1); //输出9
System.out.println(num2); //输出20
}
当使用 “||” 的时候如果第一个表达式返回值是true则第二个表达式不再执行,这也是短路现象
DEMO3 :另一种逻辑与“ | ”
public static void main(String[] args) {
int num1 = 10;
int num2 = 20;
boolean flag = 12 > --num1 | ++num2 >20 ;
System.out.println(flag); //输出true
System.out.println(num1); //输出9
System.out.println(num2); //输出21
}
使用“ | ”可以表示逻辑或运算,但是不会出现短路现象,而且“|”还可以表示位运算(后面说)。
三目运算符
、三目运算符 因为该运算需要三个操作数,所以叫做三目运算符(它也是一个三元操作符),基本的语法:condition ?value 1:value 2。其condition 是布尔类型的表达式,如果该表达式返回的值是true则最终三目运算符返回的值是 value 1,如果表达式返回的值是false 则最终返回的值是value 2。 DEMO:三目运算符
public static void main(String[] args) {
int num1 = 10;
int num2 = 20;
String content = num1>num2?"value1":"value2";
System.out.println(content); //输出value2
}
位运算的概念
位运算就是对二进制进行数字操作的一些规则,位运算在短期的开发中你是使用不到的,在以后如果你要对源进行分析或者自己研发工具会使用到,比如说 HashMap 的源中就涉及了位运算。位运算的好处是直接对计算机中的二进制数据 进行操作,速度很快,效率高。位运算分为:按位非(~)、按位与(&)、按位或 (|)、按位异或(^)、按位左移(<<)、按位右移(>>)、无符号按位右移(>>>)。 位运算除了按位非(~),其他的都是操作两个数的,因此除了(~)之外的其 他位运算符都可以叫做二元操作符,而且操作的是两个数的二进制数。
按位非运算(~)
按位非的规则是将二进制的数字每一位全部取反(0变为1,1变为0
public static void main(String[] args) {
int num1 = 10;
System.out.println(~num1); //输出-11
}
按位与运算(&)
按位运算是将参与运算的两个二进制数进行&运算,如果两个二进制位都是1, 则与运算的结果为1,其他全部都是0。
如果对应位置上的两个数字都是1 则返回1,否则返回0
public static void main(String[] args) {
int num1 = 10;
int num2 = 8
System.out.println(num1&num2); //输出8
}
总结:
-
位运算的概念:对二进制进行操作
-
位运算可以提高运算效率
-
按位非(~)和按位(&)规则
-
按位非的规则是将二进制的数字每一位全部取反(0变为1,1变为0
-
按位运算是将参与运算的两个二进制数进行&运算,如果两个二进制位都是1, 则与运算的结果为1,其他全部都是0。
-
按位或运算( | )
对应上的数只有一个是1则返回1 (两个都是1 的时候也返回1),其他情况(两者都是0)返回0
public static void main(String[] args) {
int num1 = 10;
int num2 = 8;
System.out.println(num1|num2); //输出10
}
DEMP思考(一个负数和一个正数按位或运算之后的结果是正还是呢?)
public static void main(String[] args) {
int num1 = -10;
int num2 = 8;
System.out.println(num1|num2); //输出-2
}
首先一个负数的二进制的符号位是1,正数的二进制的符号位是0,那么符号位 也要进行按位或运算,返回的是的是1,意味着最终运算后的结果的符号位还是1, 所以最终会是一个数。
总结:
-
按位或运算的符号是“|”,只有对应两位都为0 的时候运算才会位0,其他情况全部为1。
-
整数和负数按位或之后结果是负数
按位异或运算(^)
按位异或运算符的规则:只要对用位上的数据不相同就返回1,否则返回0
public static void main(String[] args) {
int num1 = 11;
int num2 = 12;
System.out.println(num1^num2); //输出7
}
DEMO:整数和负数按位与或结果是整数还是负数?
整数的符号位是0,负数的符号位是1,异或运算之后是1,所以最终结果是一个负数
public static void main(String[] args) {
int num1 = 11;
int num2 = -12;
System.out.println(num1^num2); //输出-1
}
总结:
-
按位异或运算符号是“^”,只要对应为的两个数不同就返回1,否则返回0(两位都为1或者两位都为0)
-
整数和负数异或运算之后是一个负数
-
两个负数异或运算之后是一个整数
按位左移运算(<<)
二进制位上的数据统一向左移动指定的位数,右边空出来的位置以0补齐,如果左移后超过了对应类型的最大值或者最小值则丢去符号位,否则符号位不变
public static void main(String[] args) {
int num = 12;
System.out.println(num<<3); //左移运算 12 * 2^3 = 96
}
按二进制形式把所有的数字向左移动对应的位数,高位(不是符号位)移除(舍弃),地位的空位补0,符号位不变
当左移的运算数是int类型,每移动1位它的第31位就要被移除并且丢失(左移后的数据不超过int类型的最大致和最小值)。
当左移的运算数是long类型,每移动1位它的第63位就要被移除并且丢失(左移后的数据不超过long类型的最大致和最小值)。
当左移的运算数是byte和short类型时,将自动这些类型扩大为int类型。
如果左移之后数据超出当前类型的最大致或者最小值范围,则会符号位截断丢弃,可能数的符号就会改变了。
public static void main(String[] args) {
int num = 12;
System.out.println(num<<28); //输出 = -1073741824
}
发现了结果是负数,那之前不是说符号位不变吗?既然符号位不变为什么变成负数呢?
其实当超过int类型的最大范围,则原来的符号位将被截断丢弃,使用左移后的最高位作为新的符号位。
总结:
-
按位左移符号位是“<<”,如果左移之后的数据超出当前类型的最大致或者最小值范围,则会将符号位截断丢弃,可能数的符号位就会改变了。
-
以前的面试中出现了与位运算有关的,比如请说出使用最有效的方式计算出5*8的值(5<<3)。
-
位运算是直接操作计算器内存中的二进制数据,所以效率高
带符号按位右移(>>)
二进制位上的数据统一向右移动指定的位数,低位丢弃,符号位不变,因此称带符号位右移。
public static void main(String[] args) {
System.out.println(12>>1); //左移运算 12 / 2^1 = 6
}
右移之后符号位不变的,这就是带符号位右移。
无符号按位右移(>>>)
低位溢出,高位补0,注意:无符号位右移(>>>)中的符号位(最高位)也跟着变,无符号位的意思是将符号位当做数字位看待(也就是符号位也跟着右移,原来的符号位置用0补齐)。
public static void main(String[] args) {
System.out.println(-12>>>1); //输出2147483642
}
发现了使用(>>>)运算之后符号位发生了变化,那么验证了“低位溢出,高位补0”,原来的符号位变成了0,所以一种之后数字变成了整数。
总结:
-
带符号位右移运算,符号是“>>”,符号位不变。
-
无符号位右移运算,符号是“>>>”,符号位变为0(原来的符号位跟着移动了,新的符号位就是0)。