标识符

标识符概念

  1. Java对各种变量、方法和类等命名时使用的字符序列成为标识符。
    2. 凡是自己可以起名字的地方都叫标识符。

    标识符命名规则

    1. 由26个英文字母大小写,0-9,_和$组成。
    2. 数字不可以开头。
    3. 不可以使用关键字和保留字(比如class等),但能包含关键字和保留字(a_class)。
    保留字(reserved words):现有Java版本尚未使用,但以后版本可能会作为关键字使用。如goto,const,inner等。
    关键字(keywards):被Java语言赋予了特殊含义,用作专门用途的字符串,特点是关键字中所有字母都为小写,如class,public,int等。
    4. Java中严格区分大小写,长度无限制。
    5. 标识符不能包含空格。

    标识符命名规范

    1. 包名:多单词组成时所有字母都小写,比如 com.hsp.crm
    2. 类名,接口名:多单词组成时,所有单词的首字母大写,比如 TankShotGame(大驼峰)
    3. 变量名,方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写,比如 tankShotGame(小驼峰,简称驼峰法)。
    4. 常量名:所有字母都大写,多单词组成时每个单词用下划线连接,比如 TAX_RATE。

Switch语句

流程图

image.png

  1. Scanner myScanner = new Scanner(System.in);
  2. char c = myScanner.next().charAt(0);//输入一个字符操作

注意细节

  1. switch括号里表达式的数据类型,应和case后的常量类型一致,或者是可以相互转换的类型,比如int和char。
    1. char c = 'a';
    2. switch(c) {
    3. case 11://这样不会报错
    2. switch(表达式) 中表达式必须是:byte,short,int,char,enum,String(不能是浮点型)
    1. double c = 1.1;
    2. switch(c) { //会报错
    3. case 1.1: //这样也会报错
    3. case子句中的值必须是常量,而不能是变量。
    1. char c = 'a';
    2. int b = 11;
    3. switch(c) {
    4. case b: //报错,不能是变量
  2. default语句是可选的,当没有匹配的case时,执行default。
    5. break语句用来执行完一个case分支后跳出switch语句块,如果没有写break,程序会顺序执行下一条case。
    6. 如果判断的具体数值不多,而且都符合byte,short,int,char,enum,String这6种类型,建议使用switch语句。 对区间进行判断,或者结果为boolean类型,则使用if。

数组细节

  1. 数组创建后,如果没有赋值,有默认值—— int,short,byte,long 为0。float,double为0.0。char为\u0000,String为null,boolean为false。
    2. 数组属引用类型,数组型数据是对象。
    3. 数组共有三种初始化方式,其中两种动态初始化,一种静态初始化。
    1. //第一种是动态初始化
    2. int[] a = new int[10]; //当然也可以是 int a[] = new int[10];
    3. //第二种也是动态初始化
    4. int[] a;
    5. a = new int[10];
    6. //第三种是静态初始化
    7. int[] a = {...};
    4. 数组赋值机制——值拷贝/值传递引用传递/地址拷贝 的区别:
    基本数据类型使用值拷贝,只把数值赋过去:
    1. int n1 = 2;
    2. int n2 = n1; //这里就是 值传递/值拷贝,只把数值传递过去
    3. n2 = 10; //最终n2为10,n1为2
    数组在默认情况下使用引用传递,赋的值是地址:
    1. int[] arr1 = {1,2,3};
    2. int[] arr2 = arr1; //这里就是引用传递/地址拷贝
    3. arr2[0] = 10; //arr1[0]同步修改为10
    image.png

    简朴的数组扩容方法

    整体思路:新建一个比原来数组大的数组,然后进行数组复制,把剩下的空位赋为想要的数字,然后让原来的数组指向新数组
    1. public static void main(String[] args){
    2. Scanner judge = new Scanner(System.in);
    3. int[] arr = {1,2,3,4,5};//原来的数组
    4. char h;
    5. do {
    6. System.out.println("请输入要添加的数字:");
    7. int t = judge.nextInt();//输入要添加的数字
    8. int[] arrNew = new int[arr.length + 1];//新建一个较大的数组
    9. arrNew[arr.length] = t;//把要添加的数组赋给多余位置
    10. for(int i = 0 ;i < arr.length ; i++) {
    11. arrNew[i] = arr[i];//进行数组的复制
    12. }
    13. arr = arrNew;//最关键的一步,让旧数组指向新数组
    14. for(int i = 0;i < arr.length;i++) {
    15. System.out.print(arr[i] + " ");
    16. } System.out.println();
    17. System.out.println("是否要继续输入?");
    18. h = judge.next().charAt(0);
    19. }while(h == 'y');//可以控制无限循环
    20. }
    核心代码:
    1. int[] arrNew = new int[arr.length + 1];//新建一个较大的数组
    2. arrNew[arr.length] = t;//把要添加的数组赋给多余位置
    3. for(int i = 0 ;i < arr.length ; i++) {
    4. arrNew[i] = arr[i];//进行数组的复制
    5. }
    6. arr = arrNew;//最关键的一步,让旧数组指向新数组
    结果展示:
    image.pngimage.png
    数组缩减也是同理,只不过要判断一下是否内容为空。

    二维数组

    内存示意图

    1. int arr[][] = new int[2][3];
    2. arr[1][1] = 8;
    image.png

    二维数组初始化

    1. 与一维数组类似的初始化方法:
    1. //第一种动态初始化方法
    2. int arr[][] = new int[2][3];
    3. //int[][] arr = new int[2][3];也可以
    4. //int[] arr[] = new int[2][3];也可以
    5. //第二种动态初始化方法
    6. int arr[][];
    7. arr = new int[2][3];
    8. //静态初始化方法
    9. int arr[][] = {{1,1,1,},{2,3,4},{5,6,7},{9}};
    2. 列数不确定的初始化方法:
    1. int arr[][] = new int[3][]; //不确定列数的初始化方法
    2. for (int i = 0; i < 3; i++) {
    3. arr[i] = new int[i + 1]; //列数不确定,要分配对应的空间
    4. for (int j = 0; j < i + 1; j++) {
    5. arr[i][j] = j + 1; //给数组赋内容
    6. }
    7. }
    二维数组实际上是由多个一维数组组成的,它的各个一维数组长度可以相同也可以不同。arr[i]相当于第i个数组,arr.length得到总共有多少个数组(行),而arr[i].length得出第i个数组(第i行)共有多少个元素,由于列数是不确定的,因此要单独给每一列分配空间
    image.png
    两个细节: ```java int[] x,y[]; //这里x是一维数组,y是二维数组

String strs[] = new String{“a”,”b”,”c”}; //报错,错误使用构造
String strs[] = new String[]{“a”,”b”,”c”}; //正确
String strs[] = new String[3]{“a”,”b”,”c”}; //报错,动态分配和静态分配不能在一起

  1. ![image.png](https://cdn.nlark.com/yuque/0/2022/gif/23175776/1641695350037-555d8469-43fa-4e5f-9154-ef13bb3f2456.gif#clientId=u66ade792-75c0-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u030ef74e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1&originWidth=1&originalType=url&ratio=1&rotation=0&showTitle=false&size=43&status=done&style=none&taskId=ue0183eb3-75a1-4948-aeeb-45d1b1de152&title=)
  2. <a name="nJ8w0"></a>
  3. ## **冒泡排序**
  4. <a name="BD5kE"></a>
  5. ### **两个编程思想**
  6. **1. 化繁为简:将复杂的要求,拆解成简单的需求,逐步完成。**<br />**2. 先死后活:先考虑固定的值,然后转变成可以灵活变化的值。**<br />**用化繁为简和先死后活两种编程思想讨论冒泡排序。根据先死后活原理,我们先就 [24,69,80,57,13] 这个数组进行讨论。**<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/23175776/1641697253562-b8bb129f-954b-4c2c-b1aa-742e9d34682c.png#clientId=u66ade792-75c0-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=ufc9d8cb0&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1060&originWidth=1906&originalType=url&ratio=1&rotation=0&showTitle=false&size=1675079&status=done&style=none&taskId=u1a0c3e98-cc73-4ef6-b5f3-14bfa827c71&title=)<br />** 然后根据化繁为简**,**我们先不管第几轮排序和第几次比较之间的关系**,**只讨论每一轮排序:**
  7. ```java
  8. //第一轮排序
  9. for(int j = 0;j < 4;j++){
  10. if(arr[j]>arr[j+1]){
  11. temp = arr[j];
  12. arr[j] = arr[j+1];
  13. arr[j+1]= temp;
  14. }
  15. }
  16. //第二轮排序
  17. for(int j=0;j<3;j++){
  18. if(arr[j]>arr[j+1]){
  19. temp = arr[j];
  20. arr[j] = arr[j+1];
  21. arr[j+1]= temp;
  22. }
  23. }
  24. //第三轮排序
  25. ......

可以发现,每一轮排序的内容都是一样的,只不过j的判断退出条件不太一样。看出离开每一轮排序的关系后,我们再看看怎么控制排序的轮数:

  1. for(int i = 0;i < 4;i++) // 控制轮数

然后我们就要进行从死到活中的“到活”了—— 假设数组长度为n, j每次都从0开始,判断条件是 j<n - 1 - i。i也是从0开始,i<n - 1。

  1. for(int i = 0;i<arr.length;i++){
  2. for(int j = 0;j<arr.length - 1 - i;j++){
  3. if(arr[j]>arr[j+1]){
  4. temp = arr[j];
  5. arr[j] = arr[j+1];
  6. arr[j+1] = temp;
  7. }
  8. }
  9. }