运算符

运算符:

1、算术运算符

2、赋值运算符

3、比较运算符(关系运算符)

4、逻辑运算符

5、条件运算符

6、位运算符

表达式:操作数+运算符

1、按照操作数个数的分类:

(1)一元运算符:操作数只有一个

例如:正号(+),负号(-),自增(++),自减(–),逻辑非(!),按位取反(~)

(2)二元运算符:操作数有两个

例如:加(+),减(-),乘(*),除(/),模(%)

​ 大于(>),小于(<),大于等于(>=),小于等于(<=),等于(==),不等于(!=)

​ 赋值(=,+=,-=,*=,/=,%=,>>=,<<=。。。)

​ 逻辑与(&),逻辑或(|),逻辑异或(^),短路与(&&),短路或(||)

​ 左移(<<),右移(>>),无符号右移(>>>),按位与(&),按位或(|),按位异或(^)

(3)三元运算符:操作数三个

例如: ? :

2、Java基本数据类型的运算符:

(1)算术运算符

(2)赋值运算符

(3)比较运算符

(4)逻辑运算符

(5)条件运算符

(6)位运算符(难)

1、 算术运算符

加法:+

减法:-

乘法:*

除法:/

注意:整数与整数相除,只保留整数部分

取模:% 取余 被模数%模数

注意:取模结果的正负号只看被模数

特殊:模数的负号被忽略

正号:+

+:作为单目运算时表示正数 正号:+

与其他基本数据类型计算时当做加法用 a + b

在JAVA中:+ 还表示拼接

只要+两边有一个是字符串,那么就是拼接,结果仍然是字符串

a + “+”:a变量的值 拼接上 “+”符号 ,当与字符串String类型进行运算时表示连接,计算结果是字符串String类型 “菜”+“牛” “菜牛”

负号:-

-作为单目运算符时表示负数 -5

与其他基本数据类型计算时当做减法用 a-b

自增:++

自减:–

原则:自增与自减

++/–在前的,就先自增/自减,后取值

++/–在后的,就先取值,后自增/自减

整个表达式的扫描,是从左往右扫描,如果后面的先计算的,那么前面的就暂时先放到“操作数栈”中

对于自增变量本身来说,++在前或在后都一样,自增变量都要加1

i++或++i,i就是自增变量

对于表达式来说,i++和++i不一样的,++在前,先自增,再进行其他运算,++在后,先进行其他运算,然后再自增

代码示例:

int i = 1;
i++;//i=2 int j = 1;
++j;//j=2 int a = 1;
int b = a++;//(1)先取a的值“1”放操作数栈(2)a再自增,a=2(3)再把操作数栈中的"1"赋值给b,b=1 int m = 1;
int n = ++m;//(1)m先自增,m=2(2)再取m的值“2”放操作数栈(3)再把操作数栈中的"2"赋值给n,n=1 int i = 1;
int j = i++ + ++i * i++;
/*
从左往右加载
(1)先算i++
①取i的值“1”放操作数栈
②i再自增 i=2
(2)再算++i
①i先自增 i=3
②再取i的值“3”放操作数栈
(3)再算i++
①取i的值“3”放操作数栈
②i再自增 i=4
(4)先算乘法
用操作数栈中3 * 3 = 9,并把9压会操作数栈
(5)再算求和
用操作数栈中的 1 + 9 = 10
(6)最后算赋值
j = 10
*/

2、 赋值运算符

基本赋值运算符:=

扩展赋值运算符:+=,-=,*=,/=,%=…

赋值:assign

最基本的赋值运算符:=

Java中赋值,永远是把等号=右边的赋值给左边的变量。

右边如果是常量值,那么就把常量的值直接赋值给左边的变量;

右边如果是变量,那么就把变量的值直接赋值给左边的变量;

右边如果是表达式,那么就把表达式的运算结果直接赋值给左边的变量;

扩展的赋值运算符:

+=,-=,*=,/=,%=

注意:

(1)+=等,中间是不能有空格的,即不能写成 + =

(2)如果结果的类型与左边的变量不在一样时,隐含了强制类型转换

注意:所有的赋值运算符的=左边一定是一个变量

扩展赋值运算符=右边的计算结果的类型如果比左边的大的话会强制类型转换,所以结果可能有风险。

扩展赋值运算符的计算:(1)赋值最后算(2)加载数据的顺序是把左边的变量的值先加载,再去与右边的表达式进行计算

int i = 1;
int j = 5;
j *= i++ + j++;//j = j *(i++ + j++);
/*
(1)先加载j的值“5”
(2)在计算i++
①先加载i的值“1”
②再i自增,i=2
(3)再计算j++
①先加载j的值"5"
②再j自增,j=6
(4)算 加法
i + 5 = 6
(5)算乘法
5 * 6 = 30
(6)赋值
j = 30
*/

3、 比较运算符

关系运算符,比较运算符:运算的结果只有true或false的布尔值

(1)> < >= <= !=

(2)== 判断是否相等,一定要与=赋值运算符区分开

(3)instanceof,引用数据类型的关系运算符.

大于:>

小于:<

大于等于:>=

小于等于:<=

等于:== 注意区分赋值运算符的=

不等于:!=

注意:比较表达式的运算结果一定只有true/false

比较表达式可以作为

(1)条件

(2)逻辑运算符的操作数

4、 逻辑运算符

逻辑运算符的操作数必须是布尔值,结果也是布尔值

逻辑与:&

运算规则:只有左右两边都为true,结果才为true。

例如:true & true 结果为true

false & true 结果为false

true & false 结果为false

false & false 结果为false

逻辑或:|

运算规则:只要左右两边有一个为true,结果就为true。

​ 求的就是个性,不同,两个操作数不同时,结果为真,如果相同就为假

​ 例如:true | true 结果为true

​ false | true 结果为true

​ true | false 结果为true

​ false | false 结果为false

逻辑异或:^

​ 运算规则:只有左右两边不同,结果才为true。

​ 例如:true ^ true 结果为false

​ false ^ true 结果为true

​ true ^ false 结果为true

​ false ^ false 结果为false

逻辑非:!

运算规则:布尔值取反

例如:!true 为false

!false 为true

短路与:&&

运算规则:只有左右两边都为true,结果才为true。

例如:true & true 结果为true

true & false 结果为false

false & ? 结果就为false

它和逻辑与不同的是当&&左边为false时,右边就不看了。

短路或:||

运算规则:只要左右两边有一个为true,结果就为true。

例如:true | ? 结果为treu

false | true 结果为true

false | false 结果为false

它和逻辑或不同的是当||左边为true时,右边就不看了。

开发中一般用短路与和短路或比较多

面试题:&& 和 &的区别?

&&当左边为false,右边不计算

&不管左边是true还是false,右边都要计算

5、 条件运算符

? :

语法格式:

条件表达式 ? 结果表达式1 : 结果表达式2

注意条件表达式结果必须是布尔类型

运算规则:

整个表达式的结果:当条件表达式为true时,就取结果表达式1的值,否则就取结果表达式2的值

代码示例:

(1)boolean类型
boolean marry = true;
System.out.println(marry? "已婚" : "未婚"); (2)求最值
int i = 3;
int j = 5;
int max = i>=j ? i : j;
//当i>=j时,max就赋值为i的值,否则就赋值为j的值 (3)求三个数的最大值
//找出三个整数中的最大值
int x = 3;
int y = 2;
int z = 5; int max = x>=y ? x : y;
//运行到这里,max中存的是x,y中较大者 max = max >= z ? max : z; System.out.println("max = " + max);

6、 位运算符

位运算符

效率很高,但是可读性不好

因为它是基于二进制补码直接运算的。

数轴来移动 比较好点来理解 不要这样理解右移除以2的几次方左移乘以2的几次方

用得好很高的效率 但可能很多程序员理解不好的

位运算符:操作数是整数

左移 << :右边补0

右移 >> :左边补0或1,原数最高位是1,就补1,原数最高位是0,就补0

无符号右移 >>>:左边补0

二进制位 变化 移动

/**
* 位运算符 - 移位
* 1、>> 向右移位,使用方法为 x >> n 表示 x 向右移动 n 位
* 对于正数来说,向右移位时,高位补0,低位被挤掉
* 对于负数来说,向右移位时,高位补1,低位被挤掉
*
* 2、<< 向左移位,使用方法为 x << n 表示 x 向左移动 n 位
* 不论是正数还是负数,向左移位时,都是挤掉高位,低位补0
*
* 3、>>> 无符号右移
* 不论是正数还是负数,向右移位时,高位一律补0,低位被挤掉
*
* 4、Java 中没有 <<< 运算符 【划重点】 有<<就行了
*/

eg:

public class BitOperator1 {

    public static void main(String[] args) {

        // 被 final 修饰的变量被称作【最终变量】,它是最终的、不可更改的变量 【不要当做"常量"对待】
final int x = 5 ; // 0b00000000_00000000_00000000_00000101
System.out.println( x );
// 尝试再次为 final 修饰的变量赋值
// x = 6 ; // 错误: 无法为最终变量x分配值 // 将 最终变量 x 中存储的数值向右移动1位后赋值给 y 变量
int y = x >> 1 ; // 0b0_00000000_00000000_00000000_0000010
System.out.println( y ); int z = x << 1 ; // 0b0000000_00000000_00000000_00000101_0
System.out.println( z ); System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" ); // -5【原码】: 1000_0000_0000_0000_0000_0000_0000_0101
// -5【反码】: 1111_1111_1111_1111_1111_1111_1111_1010
// -5【补码】: 1111_1111_1111_1111_1111_1111_1111_1011
final int m = -5 ; // 0b1111_1111_1111_1111_1111_1111_1111_1011
System.out.println( m ); int n = m >> 1 ; // // 0b1_1111_1111_1111_1111_1111_1111_1111_101
//【补码】1_1111_1111_1111_1111_1111_1111_1111_101
//【反码】1_1111_1111_1111_1111_1111_1111_1111_100
//【原码】1_0000_0000_0000_0000_0000_0000_0000_011
System.out.println( n ); System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" ); int p = m << 1 ; // 0b111_1111_1111_1111_1111_1111_1111_1011_0
//【补码】111_1111_1111_1111_1111_1111_1111_1011_0
//【反码】111_1111_1111_1111_1111_1111_1111_1010_1
//【原码】100_0000_0000_0000_0000_0000_0000_0101_0
System.out.println( p ); System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" ); int r = 0x7FFFFFFF ;
System.out.println( r );
int s = r << 1 ;
System.out.println( s ); } }
public class BitOperator2 {

    public static void main(String[] args) {

        final int x = 5 ; // 0b00000000_00000000_00000000_00000101
final int y = -5 ; // 0b1111_1111_1111_1111_1111_1111_1111_1011 System.out.println( x >> 1 ); // 0b0_00000000_00000000_00000000_0000010
System.out.println( y >> 1 ); // 0b1_1111_1111_1111_1111_1111_1111_1111_101 System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" ); System.out.println( x >>> 1 ); // 0b0_00000000_00000000_00000000_0000010
System.out.println( y >>> 1 ); // 0b0_1111_1111_1111_1111_1111_1111_1111_101 } }

<<

​ 运算规则:左移几位感觉就相当于乘以2的几次方

​ 二进制补码左移n位,右边补0

右移:>>

​ 运算规则:右移几位感觉就相当于除以2的几次方

无符号右移:>>>

​ 运算规则:往右移动后,左边空出来的位直接补0,不看符号位

/**
* 位运算符
* 1、| 按位或 ( 逐位或 )
* 2、& 按位与 ( 逐位与 )
* 3、^ 按位异或 (逐位异或 )
* 4、~ 按位取反 (逐位取反) 【注意连符号位也一起取反】
*/

eg:

public class BitOperator4 {

    public static void main(String[] args) {

        final int x = 5 ; // 0b00000000_00000000_00000000_00000101
final int y = 7 ; // 0b00000000_00000000_00000000_00000111 //【 5 】0b00000000_00000000_00000000_00000101
//【 7 】0b00000000_00000000_00000000_00000111
int a = x | y ; // 按位或: 0b00000000_00000000_00000000_00000111
System.out.println( a ); //【 5 】0b00000000_00000000_00000000_00000101
//【 7 】0b00000000_00000000_00000000_00000111
int b = x & y ; // 按位与: 0b00000000_00000000_00000000_00000101
System.out.println( b ); //【 5 】0b00000000_00000000_00000000_00000101
//【 7 】0b00000000_00000000_00000000_00000111
int c = x ^ y ; // 按位异或: 0b00000000_00000000_00000000_00000010
System.out.println( c ); System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" ); int r = 5 ; // 0b00000000_00000000_00000000_00000101
int s = 7 ; // 0b00000000_00000000_00000000_00000111
System.out.println( "r = " + r + " , s = " + s ); // int temp = s ; s = r ; r = temp ;
r = r ^ s ; // 0b00000000_00000000_00000000_00000010
s = r ^ s ; // 0b00000000_00000000_00000000_00000101
r = r ^ s ; // 0b00000000_00000000_00000000_00000111 System.out.println( "r = " + r + " , s = " + s ); System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" ); int j = 5 ; // 0b00000000_00000000_00000000_00000101
// 注意使用 ~ 按位取反时,会对整数的符号位也取反
int k = ~j ; //0b11111111_11111111_11111111_11111010
//【补码】 11111111_11111111_11111111_11111010
//【反码】 11111111_11111111_11111111_11111001
//【原码】 10000000_00000000_00000000_00000110
System.out.println( "j = " + j + " , k = " + k ); } }

按位与:&

​ 运算规则:

​ 1 & 1 结果为1

​ 1 & 0 结果为0

​ 0 & 1 结果为0

​ 0 & 0 结果为0

按位或:|

​ 运算规则:

​ 1 | 1 结果为1

​ 1 | 0 结果为1

​ 0 | 1 结果为1

​ 0 & 0 结果为0

按位异或:^

​ 运算规则:

​ 1 ^ 1 结果为0

​ 1 ^ 0 结果为1

​ 0 ^ 1 结果为1

​ 0 ^ 0 结果为0

按位取反:~

​ 运算规则:~0就是1

​ ~1就是0

如何区分&,|,^是逻辑运算符还是位运算符?

如果操作数是boolean类型,就是逻辑运算符,如果操作数是整数,那么就位运算符。

总结

位运算符:操作数是整数

左移 << :右边补0

右移 >> :左边补0或1,原数最高位是1,就补1,原数最高位是0,就补0

无符号右移 >>>:左边补0

按位与 & :二进制对应位置取与 ,同时为1才为1,否则为0

按位或 | :二进制对应位置取或 ,有一个为1就为1

按位异或运算 ^ :二进制对应位置取异或 ,两者不同才为1

按位取反 ~ :二进制对应位置取反 ,原来是1,变为0,原来是0变为1

说明:位运算符都是机器数直接运算的

7、 运算符优先级

算符优先级:

(1)赋值类运算符是最低的,即赋值最后算

(2)条件运算符

(3)||-> &&-> |-> ^-> & 短路 逻辑

(4)比较运算符

(5)左移右移的位运算符 << >> >>> 无符号右移:>>>

(6)算术运算符

乘、除、模高于加和减

(7)自增,自减,以及按位取反,非 ! ~

(8).(面向对象用)和()

我们如果要准确的记忆每一种运算符的优先级是困难的。

我们遵循一个原则:

(1)表达式不要写太复杂,可以分为多行

(2)如果非要混合运算,那么先算的用()括起来

关于&,|,^,看左右两边的操作数是boolean值,还是整数,来决定是逻辑运算符还是位运算符。

整数是位运算符 ^ 异或 运算符

提示说明:

(1)表达式不要太复杂

(2)先算的使用()

8、 运算符操作数类型说明

1、算术运算符

数字和单个字符可以使用算术运算符。

其中+,当用于字符串时,表示拼接。

2、赋值运算符

右边的常量值、表达式的值、变量的值的类型必须与左边的变量一致或兼容(可以实现自动类型转换)或使用强制类型转换可以成功。

3、比较运算符

其他的比较运算符都是只能用于8种基本数据类型。

其中的==和!=可以用于引用数据类型的比较,用于比较对象的地址。(后面讲)

int i = 10;
int j = 10;
System.out.println(i==j);//true char c1 = '帅';
char c2 = '帅';
System.out.println(c1 == c2);//true

4、逻辑运算符

逻辑运算符的操作数必须是boolean值

5、条件运算符

?前面必须是条件,必须是boolean值

结果表达式1和结果表达式2要保持类型一致或兼容

6、位运算符

一般用于整数系列

以上运算符都是针对基本数据类型设计的。

能够用于引用数据类型只有基本的赋值运算符=,和比较运算符中的==和!=。其他运算符都不能用于引用数据类型。

其中字符串类型还有一个+,表示拼接。

9、code

算术运算符

/*
运算符:
1、算术运算符
加:+
减:-
乘:*
除:/
特殊:整数/整数,结果只保留整数部分
取模(取余):%
特殊:只看被模数的正负号
被模数%模数
什么是取模呢 取余呢
2%3=2
正号:+
负号:-
自增 自己加自己不是的 是自己增加1
自增:++
对于自增变量本身来说,都会+1.
但是++在前还是在后,对于整个表达式的计算来说是不一样的。
++在前,先自增,然后取自增后变量的值,
++在后,先取变量的值,然后变量自增。
但是不管怎么样,自增变量的取值与自增操作一前一后一定是一起完成的。
自减:--
类同自增 */
class Test05_Arithmetic{
public static void main(String[] args){
int x = 10;
int y = 3; //System.out.println("x + y = " + x + y);//变为拼接
System.out.println("x + y = " + (x + y));
System.out.println("x - y = " + (x - y));
System.out.println("x * y = " + (x * y));
System.out.println("x / y = " + (x / y));
System.out.println("x % y = " + (x % y)); System.out.println("----------------------------------");
//特殊:只看被模数的正负号
System.out.println("5%2 = " + 5%2);//1
System.out.println("-5%2 = " + -5%2);//-1
System.out.println("5%-2 = " + 5%-2);//1
System.out.println("-5%-2 = " + -5%-2);//-1 System.out.println("----------------------------------");
int a = -3;
System.out.println(-a);//3 System.out.println("----------------------------------");
int i = 2;
i++;
System.out.println("i = " + i);//3 int j = 2;
++j;
System.out.println("j = " + j);//3 System.out.println("----------------------------------");
int m = 1;
int n = ++m;//m先自增,然后把m的值取出来赋值给n
System.out.println("m = " + m);//2
System.out.println("n = " + n);//2 System.out.println("----------------------------------");
int p = 1;
int q = p++;//(1)先取出p的值"1",先放到一个“操作数栈”,(2)然后p变量完成自增(3)把刚才放在“操作数栈”中的值赋值给q
System.out.println("p = " + p);//2
System.out.println("q = " + q);//1
System.out.println("q = " + (q = q++));//1
System.out.println("q = " + q);//1
System.out.println("----------------------------------");
int z = 1;
z = z++;//(1)先取出z的值"1",先放到一个“操作数栈”,(2)然后z自增,变为2(3)把刚才放在“操作数栈”中的值赋值给z
System.out.println("z = " + z);//1
System.out.println("z = " + z++);//1
System.out.println("z = " + z);//2
System.out.println("z = " + ++z);//3 System.out.println("----------------------------------");
int b = 1;
int c = 2;
/*
第一个:b++
(1)先取b的值“1”,先放到一个“操作数栈”,
(2)紧接着b就自增了,b=2
操作数栈
第二步:++b
(1)先b自增,b=3
(2)紧接着再取b的值“3”,先放到一个“操作数栈”,
第三步:++b
(1)先b自增,b=4
(2)紧接着再取b的值“4”,先放到一个“操作数栈”,
第四步:c++
(1)先取c的值“2”,先放到一个“操作数栈”,
(2)紧接着c自增,c=3
第五步:算乘 ++b和c++的乘法部分
4*2 = 8 然后在压回“操作数栈”,
第六步:再算 b++ + ++b + 乘的结果
1 + 3 + 8 = 12
*/
int d = b++ + ++b + ++b * c++;
System.out.println("b = " + b);//4
System.out.println("c = " + c);//3
System.out.println("d = " + d);//12
}
}

练习

class Test06_Exer3{
public static void main(String[] args){
int i = 1;
int j = 2;
/*
第一步:++i
(1)先自增,i=2
(2)在取i的值“2”,放起来
第二步:j
(1)取j的值“2”,放起来
第三步:++i
(1)先自增,i=3
(2)在取i的值"3",放起来
第四步:求乘积
2 * 3 = 6,结果放起来
第五步:求和
2 + 6 = 8
*/
System.out.println(++i + j * ++i);
}
}
/*
已知一个三位数,例如:483,如何用代码求出它的百位、十位、个位数
*/
class Test07_Exer4{
public static void main(String[] args){
int num = 483; int bai = num / 100;// 483/100 4
//int shi = num/10%10;// 483/10 48 48%10 8
int shi = num%100/10;// 483%100 83 83/10 8
int ge = num % 10;// 483%10 3 System.out.println(num + "的百位:" + bai + ",十位:" + shi +",个位:" + ge);
//483的百位:4,十位:8,个位:3
}
}
//字符串拼接
class Test08_Exer6{
public static void main(String[] args){
int no = 10;
String str = "abcdef";
String str1 = str + "xyz" + no;//abcdefxyz10 str1 = str1 + "123";//abcdefxyz10123
char c = '国'; double pi = 3.1416;
str1 = str1 + pi;//abcdefxyz101233.1416 boolean b = false;
boolean t = true;
System.out.println("" + b + t);//falsetrue
System.out.println(b + "" + t);//falsetrue
/*
System.out.println(b + t + "");
Error:(22, 30) java: 二元运算符 '+' 的操作数类型错误
第一个类型: boolean
第二个类型: boolean
* */
str1 = str1 + b;//abcdefxyz101233.1416false
str1 = str1 + c;//abcdefxyz101233.1416false国
String f = "false";
System.out.println(b + f);//falsefalse
System.out.println(f + b);//falsefalse System.out.println("str1 = " + str1);
}
}
//什么是求和  什么是拼接
class Test08_Exer7{
public static void main(String[] args){
/*
String str1 = 4;
左边是String字符串类型,右边是4int类型,它们之间无法自动类型转换
*/
//String str1 = 4;
String str2 = 3.5f + "";
System.out.println(str2); //3.5
System.out .println(3+4+"Hello!"); //7Hello!
System.out.println("Hello!"+3+4); // Hello!34
System.out.println('a'+1+"Hello!"); // 98Hello!
System.out.println("Hello"+'a'+1); //Helloa1
}
}
class Test08_Exer8{
public static void main(String[] args){
short s = 5;
// s = s-2; //short - int,结果是int
// int赋值给short Error:(8, 14) java: 不兼容的类型: 从int转换到short可能会有损失 byte b = 3;
// b = b + 4; //byte + int,结果是int
//Error:(12, 17) java: 不兼容的类型: 从int转换到byte可能会有损失
b = (byte)(b+4); //可以
System.out.println(b);// 3+4 7
char c = 'a';
int i = 5;
float d = .314F;//非标准写法,如果整数部分是0,可以省略0,但不能省略小数点
double result = c+i+d; //char + int + float,结果是float,然后自动升级为double byte byte1 = 5;
short short1 = 3;
// short t = short1 + byte1; //short + byte,结果是int
//Error:(24, 26) java: 不兼容的类型: 从int转换到short可能会有损失
int t = short1 + byte1; //short + byte,结果是int
System.out.println(t);//8
}
}

赋值运算符

/*
运算符:
2、赋值运算符
(1)基本的赋值运算符:= 赋值操作:永远是把=右边的常量值、变量中值、表达式计算的值赋值给=左边的变量,
即=左边只能是一个变量。 运算的顺序:把右边的整个表达式先算完,才会做最后的赋值操作。 (2)扩展的赋值运算符
例如:
+=
-=
*=
/=
%=
... */
class Test09_Assign{
public static void main(String[] args){
int x = 1;
int y = 2 ;
int z = 3;
// x + y = z;//=左边只能是一个变量
//Error:(31, 11) java: 意外的类型
// 需要: 变量
// 找到: 值 byte b1 = 1;
byte b2 = 2;
//b2 = b1 + b2;//右边byte + byte结果是int
b2 += b1;//等价于 b2 = (byte)(b2 + b1);
System.out.println("b1 = " + b1);//1
System.out.println("b2 = " + b2);//3 System.out.println("---------------------------");
//运算的顺序:把右边的整个表达式先算完,才会做最后的赋值操作。
int i = 1;
int j = 5;
/*
第一步 i++
(1)先取i的值 放起来
(2)i自增,i=2
第二步 求和
1 + 5 = 6
第三步 乘
j * (和) = 5 * 6 = 30
第四步 赋值 把乘积赋值给j
*/
j *= i++ + j;
System.out.println("i = " + i);//2
System.out.println("j = " + j);//30
}
}

比较运算符

*
运算符:
3、比较运算符
大于:>
小于:<
大于等于:>=
小于等于:<=
等于:==
注意,谨防与赋值的=混淆
不等于:!= 比较运算符,计算完后的结果只有两个:true,false
说明比较运算符的表达式,可以作为(1)判断的条件(2)逻辑运算符的操作数 比较运算符能够用于基本数据类型,不能用于引用数据类型。
除了==和!=,关于引用数据类型时它俩的意义后面再讲。
操作数几元
一元运算符:操作数只有一个
例如:a++ 其中a就是操作数
-a 其中a就是操作
二元运算符:需要两个操作数
例如:求和 a+b 其中a和b就是操作
比较大小 age>=18 其中的age和18都是操作数
三元运算符:需要三个操作数
...
*/
class Test10_Compare{
public static void main(String[] args){
/*
有一个变量age,表示年龄,判断是否成年(满足18岁) */
int age = 26; System.out.println("是否成年:" + (age>=18));//是否成年:true
// System.out.println("是否成年:" + age>=18);//这是先字符串拼接的 /*
比较运算符作为条件
*/
if(age >= 18){
System.out.println("祝你玩得愉快!");
}else{
System.out.println("未成年不得进入!");
} /*
有一个变量,存储的是boolean类型的值
*/
boolean flag = false;
if(flag == true){//不会修改flag里面的值
System.out.println("条件成立1");
}
//与上面的语句是等价的
if(flag){
System.out.println("条件成立2");
} if(flag = true){//不是比较,而是赋值,结果仍然是布尔值,只要是布尔值就可以作为条件
System.out.println("条件成立3");
}
System.out.println("flag = " + flag); /*
有一个变量,存储的是其他类型的值
*/
int num = 1;
if(num == 1){
System.out.println("num=1");
}
//true false 才是 最终的情况
//if(num = 1){//错误的,因为num=1是赋值表达式,结果还是int,int值是不能作为条件的
// System.out.println("num=1");
//}
}
}

逻辑运算符

/*
运算符:
4、逻辑运算符
逻辑与:&
类似于:且
true & true 结果为true
true & false 结果为false
false & true 结果为false
false & false 结果为false 多个条件是否两个都成立 两个都满足的
逻辑或:|
类似于:或
true | true 结果为true
true | false 结果为true
false | true 结果为true
false | false 结果为false
满足一个 为true
逻辑非:!
类似于:取反
!true 结果为false
!false 结果为true
逻辑异或:^
类似于:求不同
true ^ true 结果为false
true ^ false 结果为true
false ^ true 结果为true
false ^ false 结果为false
求不同 不同的为true 一样的为false
短路与:&&
结果:和&是一样的
运算规则:如果&&的左边已经是false,右边就不看了
true & true 结果为true
true & false 结果为false
false & ? 结果为false
false & ? 结果为false
段路运算
短路或:||
结果:和|是一样的
运算规则:如果||左边已经是true,右边就不看了
true | ? 结果为true
true | ? 结果为true
false | true 结果为true
false | false 结果为false
*/
class Test11_Logic{
public static void main(String[] args){
/*
判断成绩是否在70和80之间
数学:70<=score<=80
Java中:
*/
int score = -78; /*
Test11_Logic.java:14: 错误: 二元运算符 '<=' 的操作数类型错误
if( 70<=score<=80){
^
第一个类型: boolean 70<=score的运算结果是true或false
第二个类型: int
1 个错误
false<=80 int
*/
//if( 70<=score<=80){
// System.out.println("良好");
//} if(70<=score & score<=80){
System.out.println("良好");
} /*
假设成绩合理范围[0,100]
判断成绩是否小于0 或 大于100,输出成绩有误
*/
if(score<0 | score>100){
System.out.println("成绩有误");
} /*
假设成绩合理范围[0,100]
判断成绩是否在合理范围内
*/
if(score>=0 & score<=100){ }
//或下面这么写
if(!(score<0 | score>100)){ } System.out.println(true ^ true);
System.out.println(true ^ false);
System.out.println(false ^ true);
System.out.println(false ^ false); /*
短路与:&&
短路或:||
*/
int i = 1;
int j;
/*
第一步:i++
(1)先取i的值“1”,放起来
(2)在i自增,i=2
第二步:算比较
放起来的“1” == 1比较,成立
&&左边是true,不会短路
第三步:++i
(1)先自增i=3
(2)再取i的值“3”,放起来
第四步:比较
放起来的“3” == 2比较,结果是false,不成立
第五步:
左边的true && 右边的false运算,结果为false,总的if不成立,走else
*/
//if(i++ == 1 && ++i == 2){
// j = 1;
//}else{
// j = 2;
//} /*
第一步:i++
(1)先取i的值“1”,放起来
(2)在i自增,i=2
第二步:算比较
放起来的“1” == 1比较,成立
||左边是true,会发生短路,右边不看了(++i == 2)没运算 第三步:
true || ?,结果为true,总的if成立
*/
if(i++ == 1 || ++i == 2){
j = 1;
}else{
j = 2;
}
System.out.println("i = " + i);
System.out.println("j = " + j);
}
}

练习

class Test12_Exer1{
public static void main(String[] args){
int x = 1;
int y = 1;
/*
第一步:x++
(1)先取x的值“1”
(2)再x自增x = 2
第二步:比较
用“1”与2比较, 1==2,不成立,false 因为&不是短路与,不管左边是怎么样,右边继续 第三步:++y
(1)自增 y = 2
(2)取y的值“2”
第四步:比较
用“2”与2比较 2 == 2,成立,true 第五步:逻辑
false & true,结果为false,总的if不成立
*/
if(x++ == 2 & ++y==2){
x = 7;
}
//& 两个都要处理的
System.out.println("x = " + x + ",y = " + y);//x = 2,y = 2
}
}
class Test12_Exer2{
public static void main(String[] args){
int x = 1;
int y = 1;
/*
第一步:x++
(1)先取x的值“1”
(2)再x自增x = 2
第二步:比较
用“1”与2比较, 1==2,不成立,false 因为&&是短路与,左边为false,右边就不看了 第三步:逻辑
false & ?,结果为false,总的if不成立
*/
//x=1 y=1
if(x++ == 2 && ++y==2){
x = 7;
}
System.out.println("x = " + x + ",y = " + y);//x = 2,y = 1
}
}
class Test12_Exer3{
public static void main(String[] args){
int x = 1;
int y = 1;
/*
第一步:x++
(1)先取x的值“1”
(2)再x自增x = 2
第二步:比较
用“1”与1比较, 1==1,成立,true 中间是|,不是短路或,右边要继续
第三步:++y
(1)y先自增,y=2
(2)再去y的值“2”
第四步:比较
用“2”与1比较 2==1,不成立,结果为false 第五步:逻辑
true & false,结果为true,总的if成立,要执行x = 7
*/
//
if(x++ == 1 | ++y==1){
x = 7;
}
System.out.println("x = " + x + ",y = " + y);//x = 7,y = 2
}
}
class Test12_Exer4{
public static void main(String[] args){
int x = 1;
int y = 1;
/*
第一步:x++
(1)先取x的值“1”
(2)再x自增x = 2
第二步:比较
用“1”与1比较, 1==1,成立,true 中间是||,是短路或,左边已经为true,会发生短路现象,右边不看了 第五步:逻辑
true & ?,结果为true,总的if成立,要执行x = 7
*/
// x = 1 ; y =1
if(x++ == 1 || ++y==1){
x = 7;
}
System.out.println("x = " + x + ",y = " + y);//x = 7,y = 1
}
class Test13_Exer{
public static void main(String[] args){
boolean x = true;
boolean y = false;
short z = 42;
/*
第一步:z++
(1)先取z的值“42”
(2)z自增 z=43
第二步:比较
用“42”与42比较,条件成立,true 中间是&&,短路与,但是没有满足短路现象。右边继续
第三步:
取y的值false
第四步:
比较,用"false"与true比较,条件不成立,false
第五步:
true && false,结果为false,if条件不成立,z++不执行
*/
if((z++==42) && (y==true))
z++; /*
||左边:x=false,这是赋值运算,结果仍然是false
中间||,是短路或,但是没有满足短路现象,右边继续
右边:
++z:先自增z=44,然后取z的值“44”,然后与45进行比较,结果为false
左边的false || 右边的false,结果还是false,if不成立,z++不执行
*/
if((x=false) || (++z==45))
z++;
System.out.println("z = " + z);//44
}
}
class Test13_Exer2{
public static void main(String[] args){
boolean x = true;
boolean y = false;
short z = 42; /*
这里y=true是赋值,结果还是true,表示条件成立,并且y的值已经变为true
*/
if(y=true)
/*
第一步:z++
(1)先取z的值“42”
(2)z自增 z=43
第二步:比较
用“42”与42比较,条件成立,true 中间是&&,短路与,但是没有满足短路现象。右边继续
第三步:
取y的值true
第四步:
比较,用"true"与true比较,条件成立,true
第五步:
true && true,结果为true,if条件成立,z++执行
z = 44
*/
if((z++==42) && (y==true))
z++; /*
||左边:x=false,这是赋值运算,结果仍然是false
中间||,是短路或,但是没有满足短路现象,右边继续
右边:
++z:先自增z=45,然后取z的值“45”,然后与45进行比较,结果为true
左边的false || 右边的true,结果还是true,if成立,z++执行,z=46
*/
if((x=false) || (++z==45))
z++;
System.out.println("z = " + z);//46
}
}

条件运算符

/*
运算符:
5、条件运算符,
因为它是唯一的三元运算符,所以也称为三元运算符 条件表达式 ? 结果表达式1 : 结果表达式2 整个表达式包含三个部分。
运算规则:如果条件表达式成立,就取结果表达式1的值,否则就取结果表达式2的值 */
class Test14_Condition{
public static void main(String[] args){
boolean marry = false;
System.out.println(marry ? "已婚" : "未婚"); //找出x和y中的最大值
int x = 4;
int y = 4;
int max = x>=y ? x : y;
/*
等价于
if(x>=y){
max = x;
}else{
max = y;
}
*/
System.out.println(x + "," + y + "中的最大值是:" + max);
int a = 4;
int b = 5;
int m;
if (a >= b){
m = a;
}else{
m = b;
}
System.out.println(a + ","+ + b + ","+"m:" + m);
int temp = a;
a = b;
b = temp;
m = a>=b ? a : b;
System.out.println();
System.out.println(a + ","+ + b + ","+"m:" + m); }
}

位运算符

/*
运算符:(了解)
6、位运算符
效率很高,但是可读性不好
因为它是基于二进制补码直接运算的。
数轴来移动 比较好点来理解 不要这样理解右移除以2的几次方
用得好很高的效率 但可能很多程序员理解不好的 左移:<<
运算规则:<<几位,就乘以2的几次方
二进制补码左移n位,右边补0
右移:>>
运算规则:>>几位,就除以2的几次方
二进制补码右移n位,左边补0还是1,看最高位
无符号右移:>>>
运算规则:二进制补码右移n位,左边补0,对于负数来说,移完后,变为正数
没有 <<< 因为就是<< 嗯嗯
按位与:&
1 & 1 结果1
1 & 0 结果0
0 & 1 结果0
0 & 0 结果0
按位或:|
1 | 1 结果1
1 | 0 结果1
0 | 1 结果1
0 | 0 结果0
按位异或:^
1 ^ 1 结果0
1 ^ 0 结果1
0 ^ 1 结果1
0 ^ 0 结果0
按位取反:~(一元运算符)
~1为0
~0为1 */
class Test15_Bit{
public static void main(String[] args){
/*
4的二进制:0000 0100
4<<3:0 0100000
*/
System.out.println(4 << -3);//-2147483648 ???
System.out.println(4 << -32);//4
System.out.println(4 << 32);//4
System.out.println(4 << 35);//32
System.out.println(4 << 3);//等价于4乘以2的3次方,4*8=32 /*
32的二进制:0010 0000
32>>4:0000 0010
*/
System.out.println(32 >>4);//等价于32除以2的4次方,32/16 =2 /*
-32的二进制:
原码:1010 0000
反码:1101 1111
补码:1110 0000
-32>>4:1111 1110
补码:1111 1110
反码:1111 1101
原码:1000 0010
负的 右移 补1 少多少补多少
*/
System.out.println(-32 >>4);// -2 System.out.println(32 >>> 4);//和>>一样,左边补0 2
/*
-32的二进制:
原码:1000 0000 0000 0000 0000 0000 0010 0000
反码:1111 1111 1111 1111 1111 1111 1101 1111
补码:1111 1111 1111 1111 1111 1111 1110 0000
-32>>>4:0000 1111 1111 1111 1111 1111 1111 1110
最高位是0,是正数
*/
System.out.println(-32 >>> 4);//268435454 /*
32:0000 0000 0000 0000 0000 0000 0010 0000
25:0000 0000 0000 0000 0000 0000 0001 1001
32 & 25:0000 0000 0000 0000 0000 0000 0000 0000
*/
System.out.println(32 & 25);//0 /*
32:0000 0000 0000 0000 0000 0000 0010 0000
25:0000 0000 0000 0000 0000 0000 0001 1001
32 | 25:0000 0000 0000 0000 0000 0000 0011 1001
*/
System.out.println(32 | 25);//57 /*
32:0000 0000 0000 0000 0000 0000 0010 0000
25:0000 0000 0000 0000 0000 0000 0001 1001
32 | 25:0000 0000 0000 0000 0000 0000 0011 1001
*/
System.out.println(32 ^ 25);//57 /*
3:0000 0000 0000 0000 0000 0000 0000 0011
~3:1111 1111 1111 1111 1111 1111 1111 1100
补码:1111 1111 1111 1111 1111 1111 1111 1100
反码:1111 1111 1111 1111 1111 1111 1111 1011
原码:1000 0000 0000 0000 0000 0000 0000 0100 -4
*/
System.out.println(~3);//-4
}
}

运算符优先级

/*
运算符优先级:
(1)赋值类运算符是最低的,即赋值最后算
(2)条件运算符
(3)||-> &&-> |-> ^-> & 短路 逻辑
(4)比较运算符
(5)左移右移的位运算符 << >> >>> 无符号右移:>>>
(6)算术运算符
乘、除、模高于加和减
(7)自增,自减,以及按位取反,非 ! ~
(8).(面向对象用)和() 我们如果要准确的记忆每一种运算符的优先级是困难的。
我们遵循一个原则:
(1)表达式不要写太复杂,可以分为多行
(2)如果非要混合运算,那么先算的用()括起来 关于&,|,^,看左右两边的操作数是boolean值,还是整数,来决定是逻辑运算符还是位运算符。
整数是位运算符 ^ 异或 运算符
*/
class Test16_Priority{
}

练习交换两个变量的值、判断是否闰年、求最大值

交换两个变量的值

/*
交换两个变量的值
借助于第三个同样类型的变量
a b c
c = a;
a = b;
b = a;
*/
class Test17_Swap{
public static void main(String[] args){
int x = 1;
int y = 2; /*
通用的方案:适用于任意的数据类型
借助于第三个通样类型的临时变量
*/
int temp = x;//x变量中值就赋值给了temp temp = 1
x = y;//再把y中的值放到x中,x = 2
y = temp;//再把temp中的值赋值给y y=1
System.out.println("x = " + x);
System.out.println("y = " + y);
temp = x;
x = y;
y = temp;
// x = 1;
// y = 2; /*
方案二:只适用于int等整数类型 byte short int long
*/
x = x ^ y;
y = x ^ y;//(新的x) ^ 原来的y = (原来的x ^ 原来的y) ^ 原来的y = 原来的x (求不同)
x = x ^ y;//(新的x) ^ 新的y = (原来的x ^ 原来的y) ^ 原来的x = 原来的y
System.out.println("x = " + x);
System.out.println("y = " + y);
// y = x ^ y ^ y; y = x; x = x ^ y ^ x;
x = 1;
y = 2;
/*
方案三:只适用于int等整数类型
有风险,可能会溢出
*/
x = x + y;//有风险,可能会溢出 大了 超了
y = x - y;//(新的x) - 原来的y = (原来的x + 原来的y)- 原来的y = 原来的x
x = x - y;//(新的x) - 新的y = (原来的x + 原来的y) - 原来的x = 原来的y
System.out.println("x = " + x);
System.out.println("y = " + y); /*
以下不推荐
*/
x = 1;
y = 2;
x = x * y;//风险更大
y = x / y;
x = x / y;
}
}

判断是否闰年

/*
1、定义一个int类型变量,保存年份,判断这个年份是否是闰年
注:判断一年是否是闰年的标准:
1)可以被4整除,但不可被100整除
2)可以被400整除
*/
class Test18_Exer{
public static void main(String[] args){
int year = 2000; boolean result = year%4==0 && year%100!=0 || year%400==0;
System.out.println(year + (result?"是闰年":"不是闰年")); if ( year%4==0 && year%100!=0 || year%400==0){
System.out.println(year + "是闰年");
}
}
}

求最大值

//2、定义三个int类型的变量,x,y,z,随意赋值整数值,求最大值
class Test19_Exer{
public static void main(String[] args){
int x = 23;
int y = 34;
int z = 49; //int max = x>=y ? x : y;//运行完这句max中存的是x与y中的最大值
//max = max >=z ? max : z;//用新的max与z比较 int max = (x>=y ? x : y) >= z ? (x>=y ? x : y) : z;
System.out.println("max = " + max); //还不如两行的
// int min = (x<=y ? x:y) <= z ? (x<=y ? x:y) : z;
// System.out.println("min:" + min);
int min = x<=y ? x:y;//行完这句min中存的是x与y中的最小值
min = min<=z ? min :z;////用新的min与z比较
System.out.println("min:" + min);
}
}

code:https://github.com/liuawen/Learning-Java

【Java】运算符(算术、赋值、比较(关系)、逻辑、条件、位运算符)的更多相关文章

  1. java入门学习(十一)逻辑运算符和位运算符

    请关注我的博客:www.taomaipin.com 家里有急事 暂停了几天,抱歉,现在呢开始说说java的运算语句和运算符 如果想利用java的运算语句 那么就离不开java的运算符,前面第九章讲了j ...

  2. IT兄弟连 Java语法教程 位运算符

    Java定义了几个位运算符,它们都可以用于整数类型(long.int.short.byte以及char).这些运算符对操作数的单个位进行操作.表1 对位运算符进行了总结. 表1  位运算符 由于位运算 ...

  3. 恶补java基础 位运算符

    以前不知道在哪看过别人写博客里的一句话  “越学的深入觉得自己会的东西越少”.最近研究了一下java的基础算法  hash表 被一些位运算符搞的头都大了 决心花一些时间研究一下以前一直觉得没用的东西! ...

  4. Java移位运算符详解实例——左移位运算符>>、带符号的右移位运算符>>

    移位运算符也针对二进制的“位”,它主要包括:左移位运算符(<<).右移位运算符(>>>).带符号的右移位运算符(>>). 1.左移运算符左移运算符用“< ...

  5. 2.&与&&以及位运算符。

    这是单独的一块,因为一条讲不清楚(虽然内容也不够一篇),而且我之前也没好好弄清楚,所以有必要写出来. 说位运算符也是从&与&&(|与||类似)之间的区别讲起的.事实上,对于两个 ...

  6. 10.&与&&以及位运算符。

    这是单独的一块,因为一条讲不清楚(虽然内容也不够一篇),而且我之前也没好好弄清楚,所以有必要写出来. 说位运算符也是从&与&&(|与||类似)之间的区别讲起的.事实上,对于两个 ...

  7. Java 关键字、标识符、注释、常量与变量、数据类型,算术、赋值、比较、逻辑、位、三元运算符和流程控制、break、continue【3】

    若有不正之处,请多多谅解并欢迎批评指正,不甚感激.请尊重作者劳动成果: 本文原创作者:pipi-changing本文原创出处:http://www.cnblogs.com/pipi-changing/ ...

  8. 【黑马JavaSE】1.2.算术\赋值\比较\逻辑\三元运算符、方法入门、JShell编译器

    文章目录 1_1_6_05_算术运算符_四则与取模运算 1_1_6_06_算术运算符_加号的多种 1_1_6_07_算术运算符_自增自减运算 1_1_6_08_赋值运算符 这里挺关键的,为什么一个by ...

  9. java入门---运算符&算术运算符&自增自减运算符&关系运算符&位运算符

        计算机的最基本用途之一就是执行数学运算,作为一门计算机语言,Java也提供了一套丰富的运算符来操纵变量.我们可以把运算符分成以下几组: 算术运算符 关系运算符 位运算符 逻辑运算符 赋值运算符 ...

随机推荐

  1. logstash导入DNS解析数据到es中,中间有filebeat

    这个过程中,主要用logstash处理数据的时候不好处理. 在logstash-sample.conf这个配置文件中的配置,我用这个监控filebeat的5044端口 # Sample Logstas ...

  2. 基础的DOS命令

    基础的dos命令 注:所有的命令以及符号应使用英文 打开CMD的方式 开始+系统+命令提示符 Win+R 输入cmd打开控制台 略 常用的dos命令 //切换盘符的方法:直接输入想进入的盘加冒号,例如 ...

  3. Linux杂谈: gcc对结构体大小的默认处理方式

    1. 发现问题 最近在编写代码过程中发现,对一个结构体进行 sizeof 操作时,有时候大小是填充过的,有时候又没有填充. 那么,如果在代码中没有显示的指定要求编译器进行对齐时,gcc的默认处理是怎样 ...

  4. clang-format 数组初始化,多行模式

    clang-format 在格式化多行数组的初始化时不够理想.例如 int array[] = { 0, 1, 2 }; 会被格式化为: int array[] = { 0, 1, 2}; 如果在最后 ...

  5. Sqlmap 学习笔记1:sqlmap参数

    SQLMP参数分析 1 目录 1.Target Options 2.Requests Options 3.Injection Options 4.Detection Options 5.Techniq ...

  6. 最新 obs-studio vs2019 开发环境搭建 代码编译

    距离上一篇文章很久了,重新开始记录 OBS 开发相关情况,第一步就是环境搭建,第二步是构建 OBS-Studio VS 2019 开发环境搭建 下载软件和资源 软件安装没有特别说明的,下载安装即可. ...

  7. mssql不存在便插入存在不执行操作

    前言 参考:https://www.jb51.cc/mssql/76911.html 在mssql中,在记录不存在时插入记录,如果存在则不执行操作 数据库 相关语句 --创建表 CREATE TABL ...

  8. 面向切面@Aspect

    package com.imooc.demo.filter; import org.springframework.core.Ordered; import org.springframework.c ...

  9. [数据库]000 - 🍳Sysbench 数据库压力测试工具

    000 - Sysbench 数据库压力测试工具 sysbench 是一个开源的.模块化的.跨平台的多线程性能测试工具,可以用来进行CPU.内存.磁盘I/O.线程.数据库的性能测试.目前支持的数据库有 ...

  10. SpringBoot入门到精通系列教程 - Filter/WebFilter

    1. Filter简介 1.1. SpringBoot 中Filter的作用 1.2. @WebFilter 2. 基于@WebFilter的实现 2.1. SpringbootApplication ...