1. 位运算符
^、&、|、-、>>、<<、>>>,位运算就是基于二进制字节进行运算
运算符 | 运算 | 范例 |
---|---|---|
<< | 左移 | 3 << 2 =12 --> 322=12 |
>> | 右移 | 3>>1=1 --> 3/2=1 |
>>> | 无符号右移 | 3>>>1=1 --> 3/2=1 |
& | 与运算 | 6&8=2 |
或运算 | ||
^ | 异或运算 | 6^3=5 |
` | 取反运算 | ~6= -7 |
注意
没有<<<
按位异或者^
^ | 1 | 0 |
---|---|---|
1 | 0 | 1 |
0 | 1 | 0 |
- 两个相同的数字进行^运算,其结果就是0
- 0和任何数进行^运算,结果就是对应数字
- 两个变量胡翔^三次,就可以呼唤位置
int num1 = 10;
int num2 = 20;
// 第一种交换方式 借助第三方变量
//int temp = 0;
//temp = num1;
//num1 = num2;
//num2 = temp;
// 第一种交换方式 通过异或^
/*逻辑*/
//int temp = num1^num2;
//num1 = temp^num1;//num1^num2^num1
//num2 = temp^num2;//num1^num2^num2
num1 = num1^num2;
num2 = num1^num2;//num1^num2^num2
num1 = num1^num2;//num1^num2^num1
按位&
按位& | 1 | 0 |
---|---|---|
1 | 1 | 0 |
0 | 0 | 0 |
- 二进制运算都是补码运算
- 运算时符号位也会参与运算
- 一个数字如何按位&1,其结果是1时那么当前该数字最后一位[二进制中]则为1
public class Demo02{
public static void main(String[] args){
//二进制运算都是补码运算
//-3是负数 原码10000..11 -> 1 1111.. 00-> 1 1111 01
// 1 1111 101
// 0 0000 101 => 0 0000 101
System.out.println(5&-3); //结果是5
System.out.println(5&3); //结果是1
}
}
按位|
按位 | | 1 | 0 |
---|---|---|
1 | 1 | 1 |
0 | 1 | 0 |
- 二进制运算都是补码运算
- 运算时符号位也会参与运算
public class Demo02{
public static void main(String[] args){
System.out.println(5|3); //7
}
}
按位 ~
按位 ~ | 1 | 0 |
---|---|---|
0 | 1 |
- 二进制运算都是补码运算
System.out.println(~5); //-6
按位左移<<
System.out.println(-2<<3);//-16
System.out.println(2<<3);//16
- 一个数字左移N位,相当于这个数字*2N次方
- 当数字左移N位,而且N超过了数字类型的取值范围,相当于左移num<<(N%32)
按位右移>>
//<<按位左移
System.out.println(8>>2);// 2
System.out.println(-8>>2);//-2
- 当一个数字(a)右移N位之后,就是除以当前数字除以2的N次方 a>>N =>a/2^N
- 右移之后如果当前数字是正数,那么填补空位通过0,反之通过当前数字的符号位
无符号右移>>>
System.out.println(-8>>2);
System.out.println(-8>>>2);
System.out.println(8>>2);
System.out.println(8>>>2);
- 当一个正数进行无符号右移操作时和右移操作的结果是一样的
- 当一个负数进行无符号右移操作时得出的结论一定是一个正数
- 无符号右移填补空位都是通过0填补的
条件运算符
表达式1?表达式2:表达式3;
- 表达式1 的结果一定是一个boolean类型的值
- 条件运算符也是三目运算符,可以连接三个操作数
三元运算符与if-else的联系
1). 三元运算符可讲话if-else语句
2). 三元运算符
3).if后的代码块可以右多个语句
import java.util.Scanner;
public class Demo04{
public static void main(String[] args){
//声明Scanner类型的变量
Scanner input = new Scanner(System.in);
System.out.println("==请输入用户名===");
int uname = input.nextInt();
//2:声明一个变量方法存储的用户名
int regUname = 123;
//3:输出 如果用户名相同则输出恭喜登录成功 反之 用户名或者密码错误
String msg = uname==regUname?"恭喜登录成":"用户名或者密码错误";
System.out.println(uname==regUname?"恭喜登录成":"用户名或者密码错误");
}
}
执行顺序
- 首先计算表达式1的值,如果表达式1的值时true,整个条件运算符的结果表达式2的值.
- 如果表达式1的值时false,那么整个条件运算符的结果时表达式3的值
- 注意:条件运算符最后会计算出一个结果,对于该结果而言,要么直接输出,要么通过变量存储,否则编译会出错.
- 条件运算符在一定程度上帮助我们解决流程控制的问题,可以替代一部分后续学习的if语句.
2.运算符的优先级
2.1运算符优先级
- 算数>比较>逻辑>=赋值符号优先级别最低 扩展运算符
- 可以加括号提高优先级
2.2运算符优先级别深入
- 单目运算符>双目运算符>三目运算符
int i = 4;
int j = 5;
System.out.println(i++ - j+i-- >>i%2 +(i++>j?j--:j));
System.out.println(i+"=="+j)
/*
第一步:i++ - j+i-- >>i%2 +5 i的值从4变为5
第二步:5-j+i-->>i%2 +5 i的值从4变为6
第三步:5-j+6>>i%2 +5 i的值从6变为5
第四步:5-j+6>>1 +5
第五步:5-j+6>>1 +5 => 6>>1 +5 => 6>>6 =>0
*/
执行顺序
- 先括号>算数>位>关系>逻辑>三目>扩展、赋值
- 算数:++ – > * / % > + -
- 关系 > < >= <= >== !=
- 逻辑: ! > & | ^ > && ||