Bootstrap

7月15日JavaSE学习笔记

运算符

运算符优先级
优先级运算符结合性
1()括号运算符由左至右
2!、+(正号)、-(负号)一元运算符由左至右
2~位逻辑运算符由右至左
2++、--递增与递减运算符由右至左
3*、/、%算术运算符由左至右
4+、-算术运算符由左至右
5<<、>>位左移、右移运算符由左至右
6>、>=、<、<=关系运算符由左至右
7==、!=关系运算符由左至右
8&位运算符、逻辑运算符由左至右
9^位运算符、逻辑运算符由左至右
10|位运算符、逻辑运算符由左至右
11&&逻辑运算符由左至右
12||逻辑运算符由左至右
13?:条件运算符由右至左
14=、+=、-=、*=、/=、%=赋值运算符、扩展运算符由右至左

前日回顾:

算术运算符

加+、减-、乘*、除/、取余%

整型和整型运算,得到的结果是整型(int),除非有long参与得到的结果是long类型

取余%的结果的正负:        A%B得到结果的正负号和A一样

比较运算符

大于>、小于<、大于等于>=、小于等于<=、等于==、不等于!=

==在基本数据类型当中比较的是值是否一样

比较运算符得到的结果永远是布尔型(true/false)

一元自增自减运算符

a++        a--        ++a        --a

a++  后加加,先将a的值赋给表达式,然后a的值再+1

++a  前加加,先a+1,再将a的值赋给表达式

逻辑运算符

逻辑与&&     两个都为true结果才为true

逻辑或||        有一个为true结果就为true

逻辑非!         取结果的反值

短路现象

多个逻辑表达式运算,前面的表达式已经可以明确整个表达式的结果,后面的就不需要再运行了


位运算符

二进制位操作后,再将二进制转为十进制即为结果

按位与运算符

&        A&B

将A和B转成二进制,右侧对齐上下比较,两者都为1结果才为1,否则为0

按位或运算符

|        A|B

将A和B转成二进制,右侧对齐上下比较,两者有一个为1结果即为1,两个都为0结果才为0

按位异或

^        A^B

将A和B转成二进制,右侧对齐上下比较,两者不同则为1,相同则为0

反码运算

~        ~A

将二进制的0换成1,1换成0

        //按位与运算符    &   A&B
        //将A和B转成二进制,右侧对齐上下比较,两者都为1结果才为1,否则为0
        //再将二进制转为十进制即为结果
        int result = 12&11;
        //1 1 0 0
        //1 0 1 1
        System.out.println(result);

        //按位或运算
        result = 12|11;
        //将A和B转成二进制,右侧对齐上下比较,两者有一个为1结果即为1,两个都为0结果才为0
        System.out.println(result);

        //按位异或运算
        result = 12^11;
        //将A和B转成二进制,右侧对齐上下比较,两者不同则为1,相同则为0
        System.out.println(result);

        //反码运算
        result = ~11;                               //    1 0 1 1
        //反码    ~   将二进制的0换成1,1换成0        ...1 1 0 1 0 0
        System.out.println(result);//负数取反加1   1...0 0 1 0 1 1 +1 = -12
移位运算

移位运算符在程序设计中,是位操作运算符的一种,用于在二进制的基础上对数字进行平移。根据平移的方向和填充数字的规则,移位运算符主要分为三种:<<(左移)、>>(带符号右移)和>>>(无符号右移)。以下是这三种移位运算符的区别:

1. 左移运算符 <<
  • 定义:左移运算符将数的各二进制位全部左移若干位,由<<右边的数指定移动的位数,高位丢弃,低位补0
  • 特点左移n位相当于乘以2的n次方
  • 示例
    • 正数:r = 20 << 2。20的二进制补码是0001 0100,向左移动两位后变为0101 0000,结果为80
    • 负数(以-20为例):-20的二进制补码是1110 1100,左移两位后的补码为1011 0000,反码为1010 1111,原码为1101 0000,结果为-80
2. 带符号右移 >>
  • 定义:带符号右移运算符将数的各二进制位全部右移若干位,由>>右边的数指定移动的位数。对于正数,高位补0;对于负数,则高位补1。(补符号位)
  • 特点右移n位相当于除以2的n次方(向下取整)
  • 示例
    • 正数:r = 20 >> 2。20的二进制补码是0001 0100,向右移动两位后变为0000 0101,结果为5
    • 负数(以-20为例):-20的二进制补码是1110 1100,右移两位后的补码为1111 1011,反码为1111 1010,原码为1000 0101,结果为-5
3. 无符号右移 >>>
  • 定义:无符号右移运算符将数的各二进制位全部右移若干位,由>>>右边的数指定移动的位数。无论是正数还是负数,高位都补0
  • 特点:对于正数,无符号右移与带符号右移结果相同;对于负数,无符号右移会将其视为正数进行处理,结果通常远大于其原始值。
  • 示例
    • 正数:r = 20 >>> 2的结果与r = 20 >> 2相同,都是5
    • 负数(以-20为例,假设数据类型为int 32位):-20的二进制补码是11111111 11111111 11111111 11101100,右移两位后的结果为00111111 11111111 11111111 11111011,转换为十进制是1073741819
总结
  • 左移(<<):低位补0,左移n位相当于乘以2的n次方。
  • 带符号右移(>>):正数高位补0,负数高位补1,右移n位相当于除以2的n次方(向下取整)。
  • 无符号右移(>>>):无论正负,高位都补0,对于负数结果可能远大于其原始值。
  • 补充:移位运算符是最基本的运算符之一,几乎每种编程语言都包含这一运算符。移位操作中,被操作的数据被视为二进制数,移位就是将其向左或向右移动若干位的运算。移位运算符只作用于整形变量,分为两类,第一类是 long 类型,long 类型长度为 8 字节 64 位;第二类为 int 类,int 长度为 4 字节 32 位,short、byte、char 在做移位之前会自动转换为 int 型,因此与 int 规则一致, 在做完移位运算后,short、byte、char类型都将变成 int 型数据(转换过程中需要考虑高位丢失的问题)

注:位与或运算符&和 |也可以对boolean值进行运算,得到boolean值,&和&&运算结果是一样的

        boolean bool = true & false; //&和&&运算结果是一样的
        int a = 12;
        int b = 12;
        bool = a++<12 & b++>12;
        bool = a++<12 && b++>12;

问:&和&&  有什么不同?
答:&是按位与运算符,需要都转成二进制,然后按位比较,没有短路现象
       &&是逻辑与运算符,有短路现象

补充:3*16最快的计算方式就是移位   3<<4相当于乘以2的4次方


赋值运算符

=        +=        -=        *=        /=        %=

        int a = 12;
        //整数和整数算术运算的结果是整数(int)
        a += 2; //和a = a+2;不完全相同,byte需要强转
        a -= 2;
        a *= 2;
        a /= 2;
        a %= 2; //把a%2的值赋值给a

三目运算符

A?B:C

其中,A是条件(boolean类型),B和C是同一类型或者可以自动转换,A为true则返回B,否则C

        int result = true?11:33;
        System.out.println(result);
        result = 12.2!=33.99?'a':33;

        //  12.2+3? 有double参与结果为double
        System.out.println(true?3:4.0);//3.0

流程控制

条件选择分支

if...else if...else...

条件从大到小写可以减少比较提高效率

public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int score = scanner.nextInt();
        if(score>=85){
            System.out.println("优秀");
        }else if (score>=70){
            System.out.println("良好");
        }else if (score>=60){
            System.out.println("及格");
        }else{
            System.out.println("不及格");
        }
}

switch...case...default...

switch 匹配某一个变量的值,如果匹配到某一个case项,就从这个case项开始运行

运行到break或者代码块结束

所有的case项都没有匹配成功才会执行default

注:1.case项和default的顺序可以是错乱的,执行顺序不会变

        (先判断case不匹配再执行default)但是会穿透略过case判定直接向下执行语句到break

       2.switch可以匹配的类型:只能匹配byte、short、int、char、String、Enum(枚举)

            int num = 8;
            switch (num){
            default://5.进入default
                System.out.println("解析不了");//6.输出
                //如果没有break;
            case 1://1.匹配失败
                System.out.println("第一季");//7.绕过case 1直接输出
                break;//9.破坏,退出
            case 2://2.匹配失败
                System.out.println("第二季");
                break;
            case 3://3.匹配失败
                System.out.println("第三季");
                break;
            case 4://4.匹配失败
                System.out.println("第四季");
                break;
        }

穿透现象:

在switch语句中,当没有在某个case分支中使用break语句时,会出现穿透现象。穿透现象指的是程序不会在匹配到的case分支结束后跳出switch语句,而是会继续执行后续的case分支。

具体来说,当程序执行匹配的case分支之后,会继续执行下一个case分支中的代码,直到遇到break语句或者switch语句的结尾。这样可能会导致意外的行为和错误的结果。

        int num = scanner.nextInt();
        switch (num){
            case 1:     //case并列往下执行,穿透现象
            case 2:
            case 3:
                System.out.println("春季");
                break;  //1、2、3都会到break前输出"春季"
            case 4:
            case 5:
            case 6:
                System.out.println("夏季");
                break;
            case 7:
            case 8:
            case 9:
                System.out.println("秋季");
                break;
            case 10:
            case 11:
            case 12:
                System.out.println("冬季");
                break;
            default:
                System.out.println("输入错误");
        }

循环

while(继续循环的条件){

        循环体

}

        int i = 'a';//计数器
        while ( i <= 'd'){
            System.out.println((char)i);//输出a,b,c,d
            i++;//计数器自增
        }

do{

        先至少执行一次的循环体(即使循环条件不成立)

}while(继续循环的条件)

        //至少执行一次
        i = 1;
        do{
            System.out.println("条件不成立");
        }while (i>20);

for(计数器声明;循环继续的条件;计数器自增){

如果括号里只有分号,其他什么都没写,就是无限循环

}

        for(int n=0;n<10;n++){
            System.out.println(n+1);//输出1~10
        }

几种循环可以互相转换


流程控制语句

break 破坏、结束break所在的循环体

continue 跳过,继续执行下一次循环

        for(int a=1;a<100;a++){
            if(a%7==0){
                //break;//结束break所在的循环体
                continue;//跳过,执行下一次循环
            }
            System.out.println(a);
        }

break如何跳出多重循环

1.给需要的那一层循环的代码块起一个标签label,直接break label跳出对应循环

        a:for(int i=0;i<30;i++){
            b:for(int j=0;j<20;j++){
                c:for(int k=0;k<10;k++){
                    if(k==5){
                        break a;
                    }
                }
            }
        }

2.也可以不使用break,而是用一个额外的变量给循环加个锁来控制所有的循环

        boolean bool=true;//定义一个变量作为锁
        a:for(int i=0;bool&&i<30;i++){
            b:for(int j=0;bool&&j<20;j++){
                c:for(int k=0;bool&&k<10;k++){
                    if(k==5){
                        //break a;
                        bool=false;
                    }
                }
            }
        }

死循环:没有结束条件的循环,之后不能写其他代码(永远没机会执行)

无限循环:结束条件永远达不到,后面可以继续编写其他代码

        int a = 0;
        while (a<1000){}//无限循环
        for(;;){

        }
        while(true){}//死循环

数组

数组:一组有序的元素序列

数组的定义
        //定义
        int[] arr={31,52,13,84};//静态的
        int[] arrA=new int[]{23,45};
        //动态的
        int[] arrB=new int[4];//长度定义数组  [4]代表可以存放4个元素
数组的限定

1.只能存放指定类型的数据

2.数组的长度是不可变的

使用数组元素

下标从0开始,依次增加

        //使用数组中的元素  下标  从0开始依次增加
        System.out.println(arr[3]);
        System.out.println(arr);//直接输出首个元素的地址
        System.out.println(Arrays.toString(arr));//输出完整数组元素
设置元素的数据
        //设置元素的数据
        arr = new int[4];
        System.out.println(Arrays.toString(arr));
        arr[1]=34;
        arr[3]=99;
        //arr[4]=8; //ArrayIndexOutOfBoundsException数组下标越界异常

        //打印出arr数组中的所有元素
        for(int i=0;i<arr.length;i++){
            System.out.println(arr[i]);
        }
获取数组的长度
        //获取数组的长度
        System.out.println(arr.length);

二维数组

二维数组的限定:

二维数组中的一维数组个数不可变,但每个一维数组的长度可变

        //二维数组
        int[][] arrs=new int[4][2];
        arrs[0][1]=12;
        System.out.println(Arrays.deepToString(arrs));
        //二维数组的限定   一维数组的个数不可变
        arrs[2]=new int[]{1,2,3,4};//一维数组的长度可变
        System.out.println(Arrays.deepToString(arrs));

        //声明一个二维数组  使用随机数为每个元素赋值
        int[][] arrC = new int[5][4];
        for(int i=0;i< arrC.length;i++){
            System.out.println(Arrays.toString(arrC[i]));
            for(int j=0;j< arrC[i].length;j++){
                arrC[i][j]=(int)(Math.random()*80);
            }
            System.out.println(Arrays.toString(arrC[i]));

        }
        System.out.println(Arrays.deepToString(arrC));

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;