• 【Java】运算符(算术、赋值、比较(关系)、逻辑、条件、位运算符)


    运算符

    运算符:
    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的值

    代码示例:

    1boolean类型
    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

  • 相关阅读:
    ansible自动化运维04
    ansible自动化运维03
    ansible自动化运维02
    ansible自动化运维01
    mysql innodb存储引擎和一些参数优化
    Mysql 数据库常用配置命令
    zabbix server3.4 使用mailx配置邮件报警
    32_redis cluster的核心原理分析:gossip通信、jedis smart定位、主备切换
    31_redis cluster的自动化slave迁移实现更强的高可用架构的部署方案
    30_redis cluster通过master水平扩容来支撑更高的读写吞吐+海量数据
  • 原文地址:https://www.cnblogs.com/liuawen/p/12854014.html
Copyright © 2020-2023  润新知