• Java初步使用


    java 目前属于甲骨文, 长期支持版本为 java8 和 java11, 主要学习JavaEE (Java Enterprise Edition) 企业版
    java特性:

    1. 强类型 静态类型的语言
    2. 跨平台 --> 不同平台的JVM保证
    3. 解释性 --> 使用JVM解释字节码

    JVM是一台虚拟的计算机,具有指令集并使用不同的存储区域。负责执行指令,管理数据、内存、寄存器

    JDK(Java Development Kit)是什么?
    JDK 是 Java 语言的软件开发工具包,关于JDK与JRE:

    1. JDK = JRE + java开发工具
    2. JRE = JVM + 核心类库

    如果只需要运行开发好的.class文件, 只需要JRE即可

    JDK的国内下载源,见:JDK下载

    第一个程序

    创建一个Hello.java文件,写入如下内容:

    public class Hello {
        public static void main(String[] args){
            System.out.println("hello world");
        }
    }
    
    1. 文件名要与类名相同

    2. 定义方式public classpublic static void main(){xxx}

    3. 要以 ; 结尾

    4. 使用javac Hello.java编译java文件成Hello.class(字节码)

      假如报错: 错误: 编码 GBK 的不可映射字符,那是因为编码问题,只需要添加-encoding utf8即可

    5. 使用java Hello运行程序(将字节码放到JVM中解释)

    开发注意事项

    1. java源文件以.java为扩展名,源文件的基本组成部分为

    2. java应用程序的执行入口为main, 它有固定的写法:

      public static void main(String[] args){....}
      
    3. java区分大小写

    4. 语句要以 ; 结尾

    5. 一个源文件中最多只能有一个public类, 其他类不限

      public class Hello{
         public static void main(String[] args){
            System.out.println("hello 1");
         }
      
      }
      // 其他的类
      
      class Dog{
         public static void main(String[] args){
            System.out.println("hello dog");
         }
      }
      
      class Cat{
         public static void main(String[] args){
            System.out.println("hello Cat");
         }
      }
      

      编译后会生成对应类的字节码如: Dog.class Cat.class

    6. 编写风格
      有两种:行尾风格和次行风格
      行尾风格
      次行风格

    7. 包名
      多单词组成时,都小写且使用.链接,如:aaa.bbb.ccc

    8. 类名 接口名
      多单词组成时,使用大驼峰, 比如ShotGame

    9. 变量名 方法名 使用小驼峰, 比如shotGame

    10. 常量名 全大写使用_连接,比如MAX_NUM

    转义符号

    一般使用如下:

    public class Test{
        public static void main(String[] args){
            System.out.println("张三\t李四\t王五");  // 制表符
            System.out.println("你好\n世界"); // 回车
            System.out.println("c:\\d");  // \
            System.out.println("aaa\rbb");  // 换行会替换掉
            System.out.println("aaa\r\bbb");  // 换行+回车会在下一行
        }
    }
    

    注释

    java的注释分

    1. 单行注释
      public class Comment{
         public static void main(String[] args){
            // 单行注释
            /*
            多行注释
            */
            System.out.println("查看代码");
         }
      }
      
    2. 多行注释
      public class Comment{
         public static void main(String[] args){
            /*
            多行注释
            */
            System.out.println("查看代码");
         }
      }
      
    3. 文档注释
      比较重要,文档注释可以被javadoc解析成网页,其写法有固定的格式。
      /**
      * 这个类演示了文档注释
      * @author lczmx
      * @version 1.2
      */
      
      public class Comment{
         public static void main(String[] args){
            System.out.println("查看代码");
         }
      }
      
      使用命令: javadoc Comment.java -d ./docs -encoding utf8 -author -version即可解析成网页
      上面使用的是authorversion这两个标签,更多的标签见:Java 文档注释
      打开./docs/index.html即可查看文档
      看文档时需要注意java类的组织形式:
      java类组织形式

    变量定义

    有两种方式:

    public class Var{
        public static void main(String[] args){
    
            // 声明再赋值
            int a;
            a = 1;
            // 声明并赋值
            int b = 3;
            System.out.println("a=" + a + "b=" + b);
        }
    
    }
    

    +号的使用

    使用+时遵循如下规则:

    1. 两边为数值,加法运算
    2. 一边为字符串,拼接
    public class Plus{
        public static void main(String[] args){
            System.out.println(100 + 98);
            System.out.println("100" + 98);
            System.out.println(100 + 3 + "hello");
            System.out.println("hello" + 100 + 3);
            /*
            198
            10098    
            103hello 
            hello1003
             */
       
        }
    }
    
    

    基本数据类型

    基本数据类型

    注意, java的字符串不是基本数据类型,它是一个对象

    使用例子:

    public class Type{
        public static void main(String[] args) {
            // 整形
            byte a = 1;  // -128 127 2^7
            short b = 22;  // -32768 32767
            int c = 123455; // -2147483648 2147483647
            long d = 123232323L; // -9223372036854775808 9223372036854775807
    		// 形如1234 默认为int,可以手动指明为long类型
    		// 不指明时会自动转换
    		
            // 浮点型
            float f1 = 1.1234F;  
            // Java中的浮点字面值默认为双精度。要指定浮点字面值,必须在该常量后面附加一个 F 或 f 。
            double f2 = 1.231;
            // 字符
            char e = '六';  // !!!! 注意为单引号,内部就是一个数字, 所以可以 char e = 97 这样定义
            boolean f = true;  // or false
            System.out.println(a);
            System.out.println(b);
            System.out.println(c);
            System.out.println(d);
            System.out.println(f1);
            System.out.println(f2);
            System.out.println(e);
            System.out.println(f);
    
        }
    }
    

    关于浮点数的运算与比较,有点特殊:

    public class Float{
        public static void main (String[] args) {
            // 默认1.1为双精度浮点型, 需要指定F
            float f1 = 1.23456789F;
            double f2 = 1.23456789;
            System.out.println(f1); // 精度缺失
            System.out.println(f2); // 精度可以保存
    
            // 科学计数法
            double f3 = 1.23E2; // 1.23 * 10^2
            double f4 = 1.23E-2;  // 1.23 * 10^-2
            System.out.println(f3);  // 123.0
            System.out.println(f4);  // 0.0123
    
            // 比较浮点数
            // 由于计算后的浮点数在内存中为一个近似值,所以不能直接比较
            // 应该相减,小于一个固定范围视为相等(范围根据业务来)
            double money1 = 1.2;
            double money2 = 1.2;
            // 可以执行
            if ( money1 == money2 ) {
                System.out.println("money1与money2 金额相等!");
            }
            double money3;
            money3 = 0.4 * 3;  // 实质上可能是1.200000000001
            // 计算相差绝对值,是否小于固定范围
            if ( Math.abs(money1 - money3) <= 0.001 ) {
                System.out.printlnk("money1与money3 金额相等!");
            }
    
        }
    }
    

    这是因为浮点数不直接存放数字,而是存放:符号位 + 指数位 + 尾数位
    而尾数部分可能丢失,造成精度损失(所以浮点数都是近似值)

    关于字符类型,也要补充一下, 主要是编码方式的区别:

    public class CharDetail{
        public static void main(String[] args){
            // 一般使用
            char c1 = 'a';
            char c2 = 98;
            char c3 = 'a' + 2;
            // 输出
            System.out.println(c1);
            System.out.println(c2);
            System.out.println(c3);
            // =====> 输出数字
            System.out.println((int)c1);    
    
            // 1. Char两个字符表示, 对应的编码方式为unicode
            // 2. Char在内部以数字存储:
            //            a -(通过编码方式)-> 97 -> 内存
            // 3. 读取的时候会,自动将数字装换成编码方式中对应的字符
            //            内存 -> 97 -(通过编码方式)-> a
            // 补充一下字符编码
            // ASCII 8bit表示,128个字符(0~127)
            // unicode  中英文都为2字节
            // UTF-8  (1~6个字节) 大小可动态变化,英文1字节 中文3字节
            // ----------- 一个字符(即'a'或'中')可以有多个字节
        }
    }
    

    字符集中只规定了 字符的代码值 并未规定具体如何存储,编码方式解决了字符在计算机中 如何存储 的问题。

    类型转换

    即不同数据类型如何转换

    自动类型转换

    低精度可以自动向高精度转换
    有两条路线:

    // char -> int -> long -> float -> double
    //   2      4      8        4        8
    // byte -> short -> int -> long -> float -> double
    //  1        2       4      8        4        8
    

    这里有一个问题: float 4个字节可以存放 long 8个字节?
    主要原因是float/double不是直接存储数值: 浮点数的32位不是简单的直接表示大小,而是按照一定的标准分配的。其中

    1. 第1位,符号位。
    2. 接下来的8位,指数域。
    3. 剩下的23位,小数域,M的取值范围为[1,2)或[0,1)
      也就是说,浮点数在内存中的二进制值不是直接转换为十进制数值的,而是按照上述公式计算而来, 通过这个公式,虽然只用到了4个字节,但是浮点数却比长整型的最大值要大。

    一般使用的规则:

    1. 低精度可以转换成高精度, 反之不行
    2. 多种类型运算时,先转化成最大的
    3. ( byte, short ) 不可以与 char 之间相互转化
    4. byte short 和 char 之间 虽然不能转化,但是这三者之间可以进行运算,结果提升为int,自身运算也会提升
    5. boolean 不转化 为数字
    // 类型转换
    public class AutoConvert{
        public static void main(String[] args) {
            // 1. ======= 低精度可以转换成高精度
            // char -> int -> long -> float -> double
            //  2       4      8       4         8
            // byte -> short -> int -> long -> float -> double
            //  1        2       4      8       4         8
            int a = 'a';
            double b = 80;
            System.out.println(a);  // 97
            System.out.println(b);  // 80.0
    
            // 2. =========== 多种类型运算时,先转化成最大的
            int a2 = 10;
            // float b2 = a2 + 1.1;  // 不可以,因为1.1为double
            double b2 = a2 + 1.1;
            System.out.println(b2);
    
            // 3. =========== ( byte, short ) 不可以与 char 之间相互转化
            // 按照我的理解,byte 和 short 虽然有1字节和2字节大小,但是为有符号的数字
            // 所以不能让byte short 和 char之间进行转化
    
            /*
            byte c3 = 1;
            short s3 = 2;
            char char3 = c3; 
    
            */
            // 4. =========== 低精度往高精度转化,不行
            // int a4 = 1.1;
            // !! 但是 byte short 会先判断数值大小,才赋值,所以可以直接使用 1 2 3........
            byte b4 = 1;
            // !! 如果用int的话不行, 它先判断类型
            int ab4 = 2;
            // byte b44 = ab4;
            short s4 = 1;
    
            // 5. byte short 和 char 之间 虽然不能转化,但是这三者之间可以进行运算,结果提升为int
            byte b5 = 2;
            short s5 = 1;
            char c5 = 11;
    
            int result5 = b5 + s5;  // byte + short
            System.out.println(result5);  // 3
            int result6 = b5 + c5; // byte + char;
            System.out.println(result6);  // 13
            int result7 = s5 + c5; // short + char;
            System.out.println(result7);  // 12
    
            // !!! 与自身运算也是int
            int result8 = b5 + b5;  // byte + byte => int
            // short char 也是这样
            System.out.println(result8);  // 4
    
            byte num1 = 1;
            short num2 = 2;
            int num3 = 123;
            float num4 = 1.234F;
            double num5 = num1 + num2 + num3 + num4;  // => float 转化成 double
    
            System.out.println(num5);
    
            // 6. ========= boolean 不转化 为数字
            // !! 就行强制转化也不行
            /*
            boolean boo6 = true;
            int i6 = (int)boo5;
            int i6 = boo5;
            */
    
        }
    }
    

    强制类型转换

    我们可以对数值进行强制转化,不过强制类型转化 会丢失精度 或 数据溢出, 取舍权衡需要考虑好
    一般的使用形式: (type)xx

    // 高精度 -> 低精度:需要强制类型转化
    
    public class ForceConvert{
        public static void main(String[] args){
            int a = (int)2201.2;  // 精度丢失
            byte b = (byte)a;  // 数据溢出
    
            System.out.println(a);  // 2201
            System.out.println(b);  // -103 数据溢出了
            System.out.println( (byte)127 );  //  不超出范围则不会溢出 (byte 1个字节 -127 ~ 127)
        }
    
    }
    

    与字符串的相互转换

    即如何将其他类型转换成字符串和将字符串转化成其他类型
    前者需要只需要+空字符串即可
    后者需要 通过基本类型的 包装类 调用 parseXxx方法即可

    需要注意的是,字符串转字符类型,使用的是charAt(index)方法

    public class ToString{
    
        public static void main(String[] args){
            // 其他类型 => String
            char c1 = 97;
            int i1 = 2;
            float f1 = 3.14F;
            boolean b1 = true;
            String s1 = c1 + "";
            String s2 = i1 + "";
            String s3 = f1 + "";
            String s4 = b1 + "";
            //                      a 2 3.14 true
            System.out.println(  " " + s1 + " " + s2 + " " + s3 + " " + s4 );
    
        }
    }
    
    class ToOther{
    
        public static void main( String[] args ){
            // String => 其他类型
            // !! 通过基本类型的 包装类 调用 parseXxx方法即可
            // !! 属于面向对象内容
    
            // 注意Integer的写法
            String s1 = "123";
            
            int num1 = Integer.parseInt(s1);
            float num2 = Float.parseFloat(s1);
            short num3 = Short.parseShort(s1);
            // 其他的类推
            boolean b = Boolean.parseBoolean("true");
            System.out.println(num1);
            System.out.println(num2);
            System.out.println(num3);
            System.out.println(b);
    
            // !! 取字符
            System.out.println(s1.charAt(0));
    
            // !! 注意:可能不一定装换成功, 需要异常处理
        }
    }
    

    运算符

    运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等。

    算术运算符

    算术运算符 是对数值类型的变量进行运算的运算符

    运算符 运算 例子 结果
    + 正号 +7 7
    - 负号 b=11; -b -11
    + 9 + 9 18
    - 10 - 8 2
    * 7 * 8 56
    / 9 / 9 1
    % 取模(余数) 11%9 2
    ++ 自增 a=2;b=++a; a = 3;b=3
    -- 自减 a=2;b=--a a=1;b=1;
    + 字符串相加 "lcz" + "mx" “lczmx”

    需要特别注意 ++--, 它们在给其他变量赋值时,在原变量的前后的结果是不一样的,看下面的例子

    使用例子:

    public class ArithmeticOperator{
        public static void main(String[] args){
            // 注意混合运算后的结果类型
            // +
            int a = 2;
            int b = 1;
            System.out.println(a + b);  // 3
    
            // -
            System.out.println(a - b);  // 1
    
            // *
            System.out.println(a * b);  // 2
            // /
            System.out.println(a / b); // 2
    
            // ======= %
            // !! 取模运算公式
            // a % b = a - a / b * b
            System.out.println(10 % 3);  // 1
            System.out.println(-10 % 3);  // -1
            System.out.println(10 % -3);  // 1
            System.out.println(-10 % -3);  // -1
    
            // 总结一下:
            /*
            1. 正 % 正 = 正
            2. 负 % 正 = 负
            3. 正 % 负 = 正
            4. 负 % 负 = 负
    
            即 第一个数为负数时,结果为负数
            !! 假如a为double时会:
            a % b = a - (int)a / b * b
            */
    
            // ++ 和 --
            // i = j++   i = j-- : 先赋值再操作
            // i = ++j   i = --j : 先操作再赋值
            // 总结,看变量在前面还是运算符在前面
            // 变量在前,则先取变量的值,则运算
            // 运算符在前,则先运算,再取值
    
            int i = 10;
            int j = i++;
            System.out.println("i++: i = " + i + " j = " + j);
    
            i = 10;
            j = ++i;
            System.out.println("++i: i = " + i + " j = " + j);
    
            // !! 自己使用++ -- 赋值时的规则
            // 会引用一个临时变量,保存数据
            int count = 1;
            count = count++;
            // 1. 返回count使用临时变量保存,即 temp = count
            // 2. 运算++, 即 count = count + 1
            // 3. 赋值给count, 用的是temp的数据: count = temp
            System.out.println(count);  // 1
    
            count = ++count;
            // 1. 返回++使用临时变量保存
            //    count = count + 1
            //    temp = count
            // 2. 赋值给count,即 count = temp
            System.out.println(count);  // 2
        }
    
    }
    

    关系运算符

    关系运算符的结果都是boolean型,即true或者false
    使用例子如下:

    public class RelationalOperator{
        public static void main(String[] args){
            System.out.println(1 == 1);
            System.out.println(1 != 1);
            System.out.println(1 < 2);
            System.out.println(1 > 2);
            System.out.println(1 <= 2);
            System.out.println(1 >= 2);
            boolean isInstance = "lczmx" instanceof String;
            System.out.println("\"lczmx\"为String子类: " + isInstance);
        }
    }
    

    逻辑运算符

    逻辑运算符有以下几种:

    • & && 逻辑与 短路与
    • | || 逻辑或 短路或
    • ! 取反
    • ^ 逻辑异或

    解释一下:

    1. 与指的是两边同时为true时, 才为true
    2. 或指的是有一边为true时, 则为true
    3. 短路指的是不满足条件的立即返回 如(false && true), 看到false就跳出了,不看true,而逻辑则会全部看完
    4. 取反即trueflasefalsetrue
    5. 逻辑异或指的是两边布尔值不同时为true, 否则为false, 如(false^ true=> true

    重点关注: 逻辑与 短路与 逻辑或 短路或,举个例子:

    public class LogicOperator{
        public static void main(String[] args){
        int a = 3;
    	// 短路
        if (a < 2 && a++ > 10){}
        // 结果: a = 3
        System.out.println(a);
    	
    	// 逻辑
        if (a < 2 & a++ > 10){}
        // 结果: a = 4  
        System.out.println(a);
        }
    }
    

    赋值运算符

    比较简单:= += -= *= /= %=
    使用例子:

    public class AssignOperator{
        public static void main(String[] args) {
    	    int n1 = 10;
    		n1 += 4;  // n1 = n1 + 4;
    		System.out.println(n1); // 14
    		
    		n1 /= 3; // n1 = n1 /3; 
    		System.out.println(n1); // 4
    		
    		byte b = 3;
    		b += 2; // 等价于 b = (byte)(b + 2);
    	}
    }
    

    三元运算符

    相当于if-else的简写版, 格式:

    int a = 10;
    int b = 99;
    int result = a > b ? a++ : b--;
    
    

    表达式成立时, 返回的第一个a++, 否返回第二个b--

    需要主要返回类型是否为接收结果的类型

    位运算符

    7个位运算符

    • & 按位与
    • | 按位或
    • ^ 按位异或
    • ~ 按位取反
    • >> 算术右移 低位溢出, 符号位不变 并用符号位补充溢出的高位
    • << 算术左移 符号位不变 低位补0
    • >>> 无符号右移 低位溢出 到位补0

    注意: 没有<<<

    运算时注意转成补码, 取结果时注意转成原码
    使用例子:

    public class BitOperator{
    
        public static void main(String[] args){
    
            // 2 & 3
            /*
            2的原码 00000000 00000000 00000000 00000010
            3的原码 00000000 00000000 00000000 00000011
            补码相同
                &   00000000 00000000 00000000 00000010
            补码为正,原码相同
                                                    2
            */
            System.out.println(2 & 3);
            // ~-2
    
            /*
            -2的原码 10000000 00000000 00000000 00000010
                反码 11111111 11111111 11111111 11111101
                补码 11111111 11111111 11111111 11111110
                 ~   00000000 00000000 00000000 00000001
                补码为正,原码相同
                                                    1
            */
            System.out.println(~-2);
    
            // ~2
            /*
            2的原码 00000000 00000000 00000000 00000010
            补码相同
                ~   11111111 11111111 11111111 11111101
            结果反码
                    11111111 11111111 11111111 11111100
            结果原码 10000000 00000000 00000000 00000011
                                                    -3
            */
           System.out.println(~2);
    
            // 2|3
            /*
            2的原码 00000000 00000000 00000000 00000010
            3的原码 00000000 00000000 00000000 00000011
            都为正数 补码相同
                |  00000000 00000000 00000000 00000011
            结果为正数
                                                    3
            */
            System.out.println(2|3);
    
            // 2^3
            /*
            2的原码 00000000 00000000 00000000 00000010
            3的原码 00000000 00000000 00000000 00000011
            都为正数 补码相同
                |  00000000 00000000 00000000 00000001
            结果为正数
                                                    1
            */
            System.out.println(2^3);
    
            // 1 >> 2
             System.out.println(1 >> 2);
            /*
            00000001 => 000000000 => 1/2/2 = 0
            */
    
            // 1 << 2
            /*
            00000001 => 000000100 => 1*2*2 = 4
            */
            System.out.println(1 << 2);
    
            // 4 << 3
            /*
            00000100
            00100000
            => 32
            => 4 * 2 * 2 * 2 = 32
            !! 即我们无需写出位,可以直接*2或/2, 取整即可
            */
            System.out.println(4 << 3);
        
    
        }
    }
    

    运算符优先级

    如下图
    优先级

    输入输出

    输入使用Scanner类, 输出使用System.out.printlnSystem.out.print
    使用例子:

    // 1. 导入, 简单的文本扫描器
    import java.util.Scanner;
    
    public class ScannerIn{
        public static void main(String[] args) {
            // 2. 创建一个对象实例
            // 注意类型
            Scanner s = new Scanner(System.in);
            // 3. 打印提示
            System.out.println("请输入名字");
            // 4. 使用next等方法,接收用户输入
            String name = s.next();  // 字符串
            System.out.println("请输入年龄");
            int age = s.nextInt();  // int 
            System.out.println("请输入工资");
            double salary = s.nextDouble(); // double
            // !! 输入类型不对时,会报错
            System.out.println("用户信息如下:");
            System.out.println("name=" + name + "; age=" + age + "; salary=" + salary);
            // 5. 这些方法,可以看文档:https://www.matools.com/file/manual/jdk_api_1.8_google/java/util/Scanner.html
        }
    }
    

    System.out.print不会自动换行

    进制

    定义方式

    通过数字前面的标记,确定进制,默认十进制

    public class BinaryTest{
        public static void main(String[] args) {
    
            // 二进制
            int num1 = 0B10; // or 0b1234
            // 八进制
            int num2 = 010; // 0开头
            // 十进制
            int num3 = 10;
            // 十六进制
            int num4 = 0X10; // or 0xa
            System.out.println(num1);  // 2
            System.out.println(num2);  // 8
            System.out.println(num3);  // 10
            System.out.println(num4);  // 16
        }
    }
    

    十进制转其他进制

    要点:

    1. 将该数不断除以进制数, 直到商为0
    2. 将每一步的余数倒过来
    public class DecimalToOther{
        public static void main(String[] args){
            int num1 = 123;  // -> 2
            /*
            123 / 2 = 61 余 1
            61 / 2 = 30  余 1
            30 / 2 = 15 余 0
            15 / 2 = 7 余 1
            7  / 2 = 3  余 1
            3  / 2  = 1 余 1
                     1        
             */
            // => 0b01111011
            // 记得补全八位
    
            int num2 = 679;  // -> 8
            /*
            679 / 8 = 84 余 7
            84 / 8 = 10 余 4
            10 / 8 = 1 余 2
                    1 
            */
            // => 01247
    
            int num3 = 8912; // ->16
            /*
            8912 / 16 = 557 余 0
            557 / 16 = 34 余 d (13)
            34 / 16 = 2 余 2
                    2
            */
            // => 0X22E0
        }
    }
    

    其他进制转十进制

    规则:从最低为开始(右边),将每位上的数据提取出来,乘以进制的(位数-1)次方

    public class OtherToDecimal{
        int num1 = 0b110001100;
        // 0 * 2^0 + 0 * 2^1 + 1 * 2^2 + 1 * 2^3 + 0 * 2^4 + 0 * 2^5 + 0 * 2^6 + 1*2^7 + 1*2^8
        // = 0 + 0 + 4 + 8 + 0 + 0 + 0 + 128 + 256
        // =  396
    
        int num2 = 02456;
        // 6 * 8^0 + 5 * 8^1 + 4 * 8^2 + 2 * 8^3
        // = 6 + 40 + 256 + 1024
        // = 1326
    
        int num3 = 0xa45;
        // 5 * 16^0 + 4 * 16^1 + 10 * 16^2
        // = 5 + 64 + 2560
        // = 2629
    
    }
    

    二进制转八/十六进制

    要点:

    1. 分组(3 位 或 4 位一组)转换成10进制
    2. 合并即可
      注意二进制与十进制的对应关系:
     1  1 1 1 1 1
    32 16 8 4 2 1
    

    这样就可以很快得出答案了,如:111 => 1 + 2 + 4 = 7
    使用例子:

    public class BinaryToOther{
    
        public static void main(String[] args){
            int num1 = 0b11100101;  // -> 8
            /*
            11 100 101
            3   4   5
            =>0345
            */
            int num2 = 0b1110010110; // -> 16
            /*
            11 1001 0110
            3   9    6
            =>0x396
            */
        }
    }
    

    八/十六进制转二进制

    要点:

    1. 将一位数 转换为(3 位 或 4 位一组二进制)
    2. 合并即可

    注意补全

    使用例子:

    public class OtherToBinary{
    
        public static void main(String[] args){
            int num1 = 01230;
            /*
            1230
            1(001) 2(010) 3(011) 0(000)
            => 0b0000001010011000
            */
            int num2 = 0xAB29
            /*
            AB29
            A(1010) B(1011) 2(0010) 9(1001)
    
            数值太大时 只需要让8-当前值,等到小的值即可
            => 0b1010101100101001
            */
        }
    }
    

    原码反码补码

    这个问题比较重要

    主要遵循如下规则:

    1. 二进制的最高位是符号位:0表示正数,1表示负数 (将1倒过来不就是-了吗)
    2. 正数的原码,反码,补码都一样(三码合一)
    3. 负数的反码=它的原码符号位不变,其它位取反 (0->1,1->0)
    4. 负数的补码=它的反码 + 1,即 负数的反码=负数的补码 - 1
    5. 0的反码,补码都是0
    6. java没有无符号数,换言之,java中的数都是有符号的
    7. 在计算机运算的时候,都是以补码的方式来运算的 (所以需要先转成补码)
    8. 当我们看运算结果的时候,要看他的原码(结果是补码,需要转成原码)

    流程控制

    一般来说,流程控制用三种:

    1. 顺序控制 一般的代码流程,从上到下执行
    2. 分支控制 一个或多个分支执行
    3. 循环控制 可以让代码重复执行

    分支控制

    if分支

    举个例子:
    做个出票系统:根据淡旺季的月份和年龄,打印票价

    • 4-10月旺季:
      1. 成人(18-60):60
      2. 儿童(<18):半价
      3. 老人(>60):1/3
    • 淡季:
      1. 成人(18-60):40
      2. 其他:20
    import java.util.Scanner;
    public class TicketingSytem{
        public static void main(String[] args) {
            Scanner s = new Scanner(System.in);
            System.out.println("月份");
            int month = s.nextInt();
            System.out.println("年龄");
            byte yearOld = s.nextByte();
    
            if (month >= 4 && month <= 10){
                int price = 60;
                if (yearOld < 18){
                    System.out.println(price / 2);
                }else if(yearOld > 60){
                     System.out.println(price / 3);
                }else{
                     System.out.println(price);
                }
            }else{
                if (yearOld > 18 && yearOld < 60){
                     System.out.println(40);
                }else{
                    System.out.println(20);
                }
    
            }
    
        }
    }
    

    赋值作为条件时,看赋值后的变量,如boolen a= false if(a=true)=> 这样是可以执行的

    switch分支

    格式:

    switch (c){
                case 'a':
                    System.out.println("星期一");
                    break;
                 default :
                    System.out.println("未知");
                    break;
                
    	}
    

    注意事项:

    1. 表达式数据类型,应和case后的常量类型一致,或者是可以自动转成可以相互比较的类型,比如输入的是字符 而常量是int
    2. switch(表达式)中表达式的返回值必须是:(byte,short,int,char,enum,String)
    3. case子句中的值必须是常量,而不能是变量
    4. default子句是可选的,当没有匹配的case时,执行default
    5. break语句用来在执行完一个case分支后使程序跳出switch语句块;如果没有写break,程序会顺序执行到switch结尾(即不会判断case)

    使用例子:

    /*
    1.
    使用switch把小写类型的char型转为大写(键盘输入)。只转换a,b,c,d,e.
    其它的输出"other"。
    2.
    对学生成绩大于60分的,输出"合格”。低于60分的,输出"不合格”。(注:输入
    的成绩不能大于100),提示成绩/60
    3.
    根据用于指定月份,打印该月份所属的季节。3,4,5春季6,7,8夏季9,10,11
    秋季12,1,2冬季[课堂练习,提示使用穿透]
    */
    import java.util.Scanner;
    
    public class SwitchExercise{
        public static void main(String[] args){
    
            // 1 
            System.out.println("char>>>");
            Scanner scanner = new Scanner(System.in);
            char c = scanner.next().charAt(0);
            switch (c){
                case 'a':
                    System.out.println('A');
                    break;
                case 'b':
                    System.out.println('B');
                    break;
                case 'c':
                    System.out.println('C');
                    break;
                case 'd':
                    System.out.println('D');
                    break;
                case 'e':
                    System.out.println('E');
                    break;
                default:
                    System.out.println("other");
                    break;
            }
            // 2
            System.out.println("成绩>>>");
            double score = scanner.nextDouble();
            // [60, 100] => /60 = 1;
            // [0, 60)  => /60 = 0;
            switch ( (int)score / 60 ){
                case 1:
                    System.out.println("合格");
                    break;
                case 0:
                    System.out.println("不合格");
                    break;
                default:
                    System.out.println("异常数据");
                    break;
            }
    
            // 3
            System.out.println("月份>>>");
            int month = scanner.nextInt();
            switch (month){
                case 3:
                case 4:
                case 5:
                     System.out.println("春季");
                     break;
    
                case 6:
                case 7:
                case 8:
                     System.out.println("夏季");
                     break;
    
                case 9:
                case 10:
                case 11:
                     System.out.println("秋季");
                     break;
                case 12:
                case 1:
                case 2:
                     System.out.println("冬季");
                     break;
    
                
    
            }
    
    
        }
    }
    

    循环控制

    for循环

    一般使用例子:

    public class For {
        public static void main(String[] args){
            // 1.打印1~100之间所有是9的倍数的整数,统计个数及总和
            int sum = 0, count = 0;
            int start = 1, end = 100;
            int t = 9; // 倍数
            for (int i = start; i <= end; i++){
                if (i % t == 0){
                    sum += i;
                    count++;
                    // 81 90 99 
                    // 9  10  11
                }
            }
            System.out.println("sum: " + sum + " count: " + count);
    
            //打印
            /*
            0 + 5 = 5
            1 + 4 = 5
            2 + 3 = 5
            3 + 2 = 5
            4 + 1 = 5
            5 + 0 = 5
            */
            int total = 5;
            for (int i=0; i<= total; i++){
                int temp = total - i;
                System.out.println(i + " + " + temp + " = " +  total);
            }
    
        }
    }
    

    注意:

    1. 循环内部语句只有一天是,可以省略{}, 但不建议使用
    2. 多个条件可以使用,隔开,如if(int i=0,j=0; i<count; i++, j+=2)
    3. 我们可以省略初始化条件和变量迭代, 灵活使用,如for( ; i<= 10 ; )
    4. 还可以全部省略,变成死循环,如for(;;)

    关于增强for, 是一种简化迭代器书写方式
    使用例子:

    
    public class Demo{
    	public static void main(String[] args){
    	    int arr[] = {1,2,3};
    	    /**
    	    *增强for
    	    */
    	    for(int num : arr){
    	     System.out.println(num);
    	    }
    	}
    }
    

    只适合取数据,不能更改数据
    只用于数组,或实现Iterable接口的集合类上;set,list

    while循环

    使用格式:

    while (循环条件) {
        循环体(语句);
    	循环变量迭代;
    }
    

    使用例子:

    public class While{
        public static void main(String[] args){
            /*
            1.打印1一100之间所有能被3整除的数
            2.打印40一200之间所有的偶数
            */
            int end1 = 100, end2 = 200;
            int start1 = 1, start2 = 40;
    
            int t1 = 3;
            int t2 = 2;
            while (start1 <= end1){
                if (start1 % t1 == 0){
                    System.out.println(start1);
                }
                start1++;
            }
    
            while (start2 <= end2){
                if (start2 % t2 == 0){
                    System.out.println(start2);
                }
                start2++;
            }
    
    
        }
    }
    

    doWhile循环

    基本使用:

    do{
    	循环体(语句);
    	循环变量迭代;
    }while(循环条件);
    
    1. 先执行在判断,即至少执行一次
    2. while后面有;

    流程图:
    流程

    使用例子:

    import java.util.Scanner;
    
    public class DoWhile{
        public static void main(String[] args){
    
            // 一般使用
            // !! 至少会执行一次
            // ! 不要忘记while后面的 ';' 了
            int c = 0;
            do {
                System.out.println("lczmx " + c);
                c++;
            }while(c > 10);
    
            // 统计1 - 200之间能被5整除但不能被3整除的个数
            byte num1 = 5;
            byte num2 = 3;
            int i = 1;
            int count = 0;
            do {
                if(i % num1 == 0 && i % num2 != 0){
                    count++;
                }
                  i++;
            }while(i<=200);
            System.out.println("count " + count);
    
            // 如果李三不还钱,打到张三说还钱为止
            Scanner scanner = new Scanner(System.in);
            char input;
            do{
                System.out.println("打!!\n还钱? y or n >>>");
                input = scanner.next().charAt(0);
            }while(input != 'y');
    
        }
    }
    

    break和continue

    • break跳出当前循环
    • continue跳过本次循环

    它们都可以指定Label,跳到对应的俄循环中

    默认是当前的循环

    使用例子:

    lable1:
    for (int j = 0; j < 4; j++) {
    lable2:
            for (int i = 0; i<10;i++) {
    		    if(i == 2){
    			    break lable1
    			}
    		 }
    }
    

    同理,continue也可以像上面那样操作

    本文根据韩顺平 零基础30天学会Java视频整理而来

  • 相关阅读:
    BZOJ3578:GTY的人类基因组计划2(集合hash,STL)
    【BZOJ 1022】 [SHOI2008]小约翰的游戏John
    【BZOJ 1295】 [SCOI2009]最长距离
    【BZOJ 1103】 [POI2007]大都市meg
    【BZOJ 3172】 [Tjoi2013]单词
    【BZOJ 1067】 [SCOI2007]降雨量
    【BZOJ 1491】 [NOI2007]社交网络
    【BZOJ 1087】[SCOI2005]互不侵犯King
    【BZOJ 1009】 [HNOI2008]GT考试
    【BZOJ 1053】[HAOI2007]反素数ant
  • 原文地址:https://www.cnblogs.com/lczmx/p/16029443.html
Copyright © 2020-2023  润新知