java特性和优势

简单性、面向对象、可移植性、高能性、分布式、动态性、多线程、安全性、健壮性。

Java基本语法

标识符注意点

  1. 所有的标识符都应该以字母(A-Z 或者a-z) ,美元符($)、或者下划线( )开始

  2. 首字符之后可以是字母(A-Z 或者a-z) ,美元符($) 、下划线(或数字的任何字符组合

  3. 不能使用关键字作为变量名或方法名。

  4. 标识符是大小写敏感的

  5. 可以使用中文命名,但是一般不建议这样去使用,也不建议使用拼音,很Low

  6. 数字字母下滑线,数字不能开头

数据类型

强类型语言

要求变量的使用要严格符合规定,所有变量都必须先定义后才能使用

弱类型语言

  1. Java的数据类型分为两大类 基本类型(primitive type) 引用类型(reference type)

  2. 浮点数拓展?银行业务怎么 表示?钱(BigDecimal数学工具类) //float(double) 有限 离散 舍入误差,大约接近但不等于

  3.  

什么是字节

  1. 位(bit) :是计算机内部数据储存的最小单位,11001100是一 个八位二进制数。

  2. 字节(byte) :是计算机中数据处理的基本单位,习惯上用大写B来表示,

  3. 1B (byte,字节) = 8bit (位)

  4. 字符:是指计算机中使用的字母、数字、字和符号

类型转换

由于Java是强类型语言,所以要进行有些运算的时候的,需要用到类型转换。

  • 低-------------------------------> 高 byte, short,char-> int -> long-> float -> double

  • 运算中,不同类型的数据先转化为同一类型,然后进行运算。

    • 强制类型转换

      高-->低

    • 自动类型转换

      低-->高

注意点:

  1. 不能对布尔值进行转换

  2. 不能把对象类型转换为不相干的类型

  3. 在把高容量转换到低容量的时候,强制转换

  4. 转换的时候可能存在内存溢出,或者精度问题! 

变量

  1. 变量是什么:就是可以变化的量!

  2. Java是一种强类型语言,每个变量都必须声明其类型。

  3. Java变量是程序中最基本的存储单元,其要素包括变量名,变量类型和作用域。

    type varName [=value] [{,varName[=value]}] ;
    //数据类型变量名 =值;可以使用逗号隔开来声明多个同类型变量。
  1. 注意事项:

  • 每个变量都有类型,类型可以是基本类型,也可以是引用类型。

  • 变量名必须是合法的标识符。

  • 变量声明是一条完整的语句,因此每一个声明都必须以分号结束

public class demo01 {
   //类变量static
   static double salary = 2500;
   //属性:变量
   //实例变量:从属于对象;如果不自行初始化,这个类型的默认值 0.0
   //布尔值:默认是false
   //除了基本类型,其余的默认值都是nulL;
   String name;
   int age;
   //main方法
   public static void main(String[] args) {
       //局部变量;必须声明和初始化值
       int i=10;
       System.out. println(i);
       //变量类型变量名字 = new Demo08();
       demo01 demo01 = new demo01();
       System. out. println(demo01.age);
       System. out . println(demo01. name);
       //类变量static
       System.out. println(salary);
  }
   //其他方法
   public void add(){
  }
}

常量

常量(Constant): 初始化(initialize)后不能再改变值!不会变动的值。

所谓常量可以理解成一种特殊的变量,它的值被设定后,在程序运行过程中不允许被改变.

final常量名=值;
final double PI=3.14;

常量名一般使用大写字符。

变量的命名规范

  1. 所有变量、方法、类名:见名知义

  2. 类成员变量:首字母小写和驼峰原则: monthSalary

  3. 局部变量:首字母小写和驼峰原则

  4. 常量:大写字母和下划线: MAX_ VALUE

  5. 类名:首字母大写和驼峰原则: Man, GoodMan

  6. 方法名:首字母小写和驼峰原则: run(), runRun()

  7. 类成员变量:首字母小写和驼峰原则: monthSalary

  8. 局部变量:首字母小写和驼峰原则

  9. 常量:大写字母和下划线: MAX_ VALUE

  10. 类名:首字母大写和驼峰原则: Man, GoodMan

  11. 方法名:首字母小写和驼峰原则: run(), runRun()

运算法

  1. 算术运算符

    short+bety+long+int-->存在long为long,否则结果为int

    存在double则为double

  1. a++、++a

    int b = a++; //执行完这行代码后, 先给b赋值,再自增
    int c = ++a; ////执行完这行代码前, 先自增,再给b赋值
  2. 位运算符

    <<、>>效率极快

  3. 字符串连接符+

    System . out .println("" +a+b);//""先和a拼接,在和b拼接,a+b不进行算术运算
    System . out. println(a+b+"");//a+b先进行算术运算,在和""拼接

包机制

  1. 为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间。

  2. 包语句的语法格式为:

    package pkg1[. pkg2[. pk...]];
  3. 一般利用公司域名倒置作为包名;

  4. 为了能够使用某一个包的成员,我们需要在Java程序中明确导入该包。使用"import"语句可 完成此功能

    import package1[. package..].(classname |*);

Java Doc

  1. javadoc命令是用来生成自己API文档的

  2. 参数信息

    • @author作者名

    • @version 版本号

    • @since 指明需要最早使用的jdk版本

    • @param参数名

    • @return 返回值情况

    • @throws 异常抛出情况

Java流程控制

Scanner对象

  1. 之前我们学的基本语法中我们并没有实现程序和人的交互,但是Java给我们提供了这样一个工具类,我们可以获取用户的输入。

  2. java.util.Scanner 是Java5的新特征,我们可以通过Scanner类来获取用户的输入。

  3. 基本语法:

    Scanner S = new Scanner( System. in);
  1. 通过Scanner类的next()与nextLine()方法获取输入的字符串,在读取前我们一般需要使用hasNext()与hasNextLine()判断是否还有输入的数据。

    • next()和hasNext()

      public class Demo02_Scanner {
         public static void main(String[] args) {
             //创建一个扫描器对象,用于接收键盘数据
             Scanner scanner = new Scanner(System.in);
             System.out.println("使用next方式接收: ");
             //判断用户有没有输入字符串
             if (scanner.hasNext()){
                 //使用next方式接收
                 String str = scanner.next();//程序会等待输入内容,不输入会卡在这里
                 System.out.println("输出的内容为: "+str);
            }
             //凡是属于IO流的类如果不关闭会一直占用资源.要养成好习惯用完就关掉
             scanner.close();
        }
      }
    • nextLine()和hasNextLine()

      public class Demo02_Scanner {
         public static void main(String[] args) {
             Scanner scanner = new Scanner(System.in);
             System.out.println("使用nextLine方式接收: ");
             //判断是否还有输入
             if (scanner.hasNextLine()) {
                 String str = scanner.nextLine();
                 System.out.println("输出的内容为: " + str);
            }
             scanner.close();
        }
      }
    • next():

      • 一定要读取到有效字符后才可以结束输入。

      • 对输入有效字符之前遇到的空白,next() 方法会自动将其去掉。

      • 只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。

      • next() 不能得到带有空格的字符串。

    • nextLine():

      • 以Enter为结束符,也就是说nextLine()方法返回的是输入回车之前的所有字符。

      • 可以获得空白。

  2. 使用语法

    public class Demo02_Scanner {
       public static void main(String[] args) {
    Scanner scanner = new Scanner(System. in);
       System.out.println("请输入数据: ");
    String str = scanner.nextLine( );
    System.out .println( "输出的内容为: "+str);
    scanner.close();
      }
    }
  1. 其他hasNextInt()和hasNextFloat()

    public class Demo03_Scanner {
       public static void main(String[] args) {
           Scanner scanner = new Scanner(System.in);
           //从键盘接收数据
           int i = 0;
           float f = 0.0f;
           System.out.println("请输入整数: ");
           if (scanner.hasNextInt()) {
               i = scanner.nextInt();
               System.out.println("整数数据: " + i);
          } else {
               System.out.println("输入的不是整数数据! ");
          }
           System.out.println("请输入小数: ");
           if (scanner.hasNextFloat()) {
               f = scanner.nextFloat();
               System.out.println("小数数据: " + f);
          } else {
               System.out.println("输入的不是小数数据! ");
          }
           scanner.close();
      }
    }
  1. 输入多个数字,并求其总和与平均数

import java.util.Scanner;

public class Demo04_Scanner {
   public static void main(String[] args) {
       //我们可以输入多个数字,并求其总和与平均数,每输入一个数字用回车确认,通过输入非数字来结束输入并输出执行结果:
       Scanner scanner = new Scanner(System.in);
       double sum = 0;
       int m = 0;
       //通过循环判断是否还有输入,并在里面对每-次进行求和和统计
       while (scanner.hasNextDouble()){
           double x = scanner.nextDouble();
           m=m+1; //m++
           sum=sum+x;
           System.out.println("你输入了第"+m+"个数据,然后当前结果sum=" +sum) ;
      }
       System.out.println(m + "个数的和为" + sum);
       System.out.println(m +"个数的平均值是" + (sum / m));
       scanner.close();
  }
}

switch多选择结构

  1. 多选择结构还有一个实现方式就是switch case语句。

  2. switch case语句判断一个变量与一系列值中某个值是否相等,每个值称为一个分支。

  3. switch 语句中的变量类型可以是:

    • byte、short, int 或者char.

    • 从JavaSE7开始,switch支持字符串String类型了

      • 字符的本质是数字

      • java文件

      public class Demo05_Switch {
         public static void main(String[] args) {
             String name = "狂神";
             switch (name){
                 case "秦疆":
                     System.out.println("秦疆");
                     break;
                 case "狂神":
                      System.out.println("狂神");
                      break;
                 default :
                     System.out.println("弄啥嘞! ");
            }
        }
      }
      • class文件(hashCode())

        //
        // Source code recreated from a .class file by IntelliJ IDEA
        // (powered by Fernflower decompiler)
        //

        package com.base;

        public class Demo05_Switch {
          public Demo05_Switch() {
          }

          public static void main(String[] args) {
              String name = "狂神";
              byte var3 = -1;
              switch(name.hashCode()) {
              case 941788:
                  if (name.equals("狂神")) {
                      var3 = 1;
                  }
                  break;
              case 997472:
                  if (name.equals("秦疆")) {
                      var3 = 0;
                  }
              }

              switch(var3) {
              case 0:
                  System.out.println("秦疆");
                  break;
              case 1:
                  System.out.println("狂神");
                  break;
              default:
                  System.out.println("弄啥嘞! ");
              }

          }
        }
    • 同时case标签必须为字符串常量或字面量。

增强for循环

  1. 这里我们先只是见一面,做个了解,之后数组我们重点使用

  2. Java5引入了一种主要用于数组或集合的增强型for循环。

  3. Java增强for循环语法格式如下:

    for(声明语句:表达式)
    {
    //代码句子
    }
    • 声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循 环语句块,其值与此时数组元素的值相等。

    • 表达式:表达式是要访问的数组名,或者是返回值为数组的方法。

public class Demo06_Foreach {
   public static void main(String[] args) {
       int[] numbers = {10,20,30,40,50}; //定义了一个数组
       //遍历数组的元素
       for (int x: numbers){
           System.out.println(x);
      }
  }
}

break continue

  1. break在任何循环语句的主体部分,均可用break控制循环的流程。break用于强行退出循环,不执行循环中剩余的语句。(break语句也在switch语句中使用)

  2. continue语句用在循环语句体中,用于终止某次循环过程,即跳过循环体中尚未执行的语句,接着进行下一次是否执行循环的判定。

  3. 关于goto关键字 goto关键字很早就在程序设计语言中出现。尽管goto仍是Java的- 个保留字,但并未在语言中得到正式使用; Java没有goto。然而,在break和continue这两个关键字的身上,我们仍然能看出一些goto的影子——带标签的break和continue.

    • "标签" 是指后面跟一个冒号的标识符,例如: label:

    • 对Java来说唯一 用到标签的地方是在循环语句之前。 而在循环之前设置标签的唯一理由是:我们希望在其中嵌套另一个循环,由于break和continue关键字通常只中断当前循环,但若随同标签使用,它们就会中断到存在标签的地方。

public class Demo07_Label {
   public static void main(String[] args) {
       //打101- 150之问所有的质数
       int count = 0;
       //不建议使用!
       outer:for (int i = 101;i < 150;i++){
           for (int j = 2; j < i/2;j++){
               if (i %j== 0){
                   continue outer;
              }
          }
           System.out.print(i+" ");
      }
  }
}
方法

何谓方法?

  1. System.out.println(), 那么它是什么呢?

  2. Java方法是语句的集合,它们在一起执行一个功能。

    • 方法是解决一类问题的步骤的有序组合

    • 方法包含于类或对象中

    • 方法在程序中被创建, 在其他地方被引用

  3. 设计方法的原则:方法的本意是功能块,就是实现某个功能的语句块的集合。我们设计方法的时候,最好保持方法的原子性,就是一个方法只完成1个功能,这样利于我们后期的扩展

  1. 回顾:方法的命名规则?

方法的定义

  1. Java的方法类似于其它语言的函数,是-段用来完成特定功能的代码片段,一般情况下,定义一个方法包含以下语法:

    • 方法包含一个方法头和一个方法体。下面是一个方法的所有部分:

    • 修饰符:修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。

    • 返回值类型:方法可能会返回值。returnValueType 是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType 是关键字void。

    • 方法名:是方法的实际名称。方法名和参数表共同构成方法签名。

    • 参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。

      • 形式参数:在方法被调用时用于接收外界输入的数据。

      • 实参:调用方法时实际传给方法的数据。

    • 方法体:方法体包含具体的语句,定义该方法的功能。

      修饰符 返回值 类型 方法名(参数类型参数名){
      方法体
      return返回值;
      }

方法调用

  1. 调用方法:对象名.方法名(实参列表)

  2. Java支持两种调用方法的方式,根据方法是否返回值来选择。

    • 当方法返回一个值的时候,方法调用通常被当做一个值。例如: int larger = max(30,40);

    • 如果方法返回值是void,方法调用一定是一条语句。 System. out. println( "Hello, kuangshen!");

  3. 课后拓展了解:值传递(Java)和引用传递

方法的重载

  1. 重载就是在一个类中,有相同的函数名称,但形参不同的函数。

  2. 方法的重载的规则:

    • 方法名称必须相同。

    • 参数列表必须不同(个数不同、或类型不同、参数排列顺序不同等)。

    • 方法的返回类型可以相同也可以不相同。

    • 仅仅返回类型不同不足以成为方法的重载。

  3. 实现理论:

    方法名称相同时,编译器会根据调用方法的参数个数、参数类型等去逐个匹配,以选择对应的方法,如果匹配失败,则编译器报错。

命令行传参

有时候你希望运行一个程序时候再传递给它消息。这要靠传递命令行参数给main()函数实现。

public class CommandLine {
public static void main(String args[]){
for(int i=0; i<args.length; i++){
System. out. println("args["+ i + "]:"+ args[i]);
}
}
}

可变参数

  1. JDK 1.5开始,Java支持传递同类型的可变参数(不定项)给一个方法。

  2. 在方法声明中,在指定参数类型后加一个省略号(..)。

  3. 一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它之前声明。

public class Demo08 {
   public static void main(String args[]) {
       //调用可变参数的方法
       printMax(15,22.0,36,25.3);
       printMax(new double[]{1, 2, 3});//本质为数组

  }
   public static void printMax(double... numbers) {
       if (numbers.length == 0) {
           System.out.println("No argument passed");
           return;
      }
       double result = numbers[0];
       //排序!
       for (int i = 1; i < numbers.length; i++) {
           if (numbers[i] > result) {
               result = numbers[i];
          }
      }
       System.out.println("The max value is " + result);
  }
}

递归(能不用就不用)

  1. 递归就是: A方法调用A方法!就是自己调用自己

  2. 利用递归可以用简单的程序来解决一些复杂的问题。 它通常把一个大型复杂的问题层层转化为-个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。

  3. 递归结构包括两个部分:

    • 递归头:什么时候不调用自身方法。如果没有头,将陷入死循环。

    • 递归体:什么时候需要调用自身方法。

Java数组

数组的定义

  1. 数组是相同类型数据的有序集合.

  2. 数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。

  3. 其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们.

数组声明创建

  1. 首先必须声明数组变量,才能在程序中使用数组。下面是声明数组变量的语法:

    dataType[] arrayRefVar; // 首选的方法

    dataType arrayRefVar[]; // 效果相同,但不是首选方法
  2. Java语言使用new操作符来创建数组,语法如下:

    dataType[] arrayRefVar = new dataType[arraySize] ;
  3. 数组的元素是通过索引访问的,数组索引从0开始。

    • 获取数组长度:arrays . length

int[] nums; //1.声明-一个数组
nums = new int[10]; //2. 创建一个数组
nums[0] = 1;//3.给数组元素中赋值

三种初始化

  1. 静态初始化

    int[] a = {1,2,3};
    Man[] mans = {new Man(1,1) , new Man(2,2)};
  2. 动态初始化

    int[] a = new int[2]; 
    a[0]=1;
    a[1]=2;
  3. 数组的默认初始化

    数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。

数组的四个基本特点

  1. 其长度是确定的。数组一旦被创建,它的大小就是不可以改变的。

  2. 其元素必须是相同类型,不允许出现混合类型。

  3. 数组中的元素可以是任何数据类型,包括基本类型和引用类型。

  4. 数组变量属引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量。

  5. 数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的。

小结:

  1. 数组是相同数据类型(数据类型可以为任意类型)的有序集合

  2. 数组也是对象。数组元素相当于对象的成员变量

  3. 数组长度的确定的,不可变的。如果越界,则报: ArrayIndexOutofBounds

数组使用

  1. For-Each循环

    public class Demo09_Array {
       public static void main(String[] args) {
           int[] arrays = {1,2,3,4,5};
           //JDK1.5,没有下标
           for (int array : arrays) {
               System.out.println(array);
          }
      }
    }
  2. 数组作方法入参

    public class Demo09_Array {
       public static void main(String[] args) {
           int[] arrays = {1,2,3,4,5};
           printArray(arrays);
      }
       //打印数组元素
       public static void printArray(int[] arrays){
           for (int i = 0; i < arrays.length; i++) {
               System.out.print(arrays[i]+" ");
          }
      }
    }
  3. 数组作返回值

    public class Demo09_Array {
       public static void main(String[] args) {
           int[] arrays = {1,2,3,4,5};
           int[] reverse = reverse( arrays);
           printArray(reverse);
      }
       //反转数组
       public static int[] reverse(int[] arrays){
           int[] result = new int [arrays.length];
           //反转的操作
           for (int i = 0,j=result.length-1; i < arrays.length; i++,j--) {
               result[j] = arrays[i];
          }
           return result;
      }
       //打印数组元素
       public static void printArray(int[] arrays){
           for (int i = 0; i < arrays.length; i++) {
               System.out.print(arrays[i]+" ");
          }
      }
    }

多维数组

  1. 多维数组可以看成是数组的数组,比如维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组。

  2. 二维数组

    int a[][] = new int[2][5];
    • 解析:二维数组a可以看成一个两行三列的数组。

  3. 思考:多维数组的使用?

Arrays类

  1. 数组的工具类java.util.Arrays

  2. 由于数组对象本身并没有什么方法可以供我们调用,但API中提供了-一个工具类Arrays供我们使用,从而可以对数据对象进行一些基本的操作。

    查看JDK帮助文档

  1. Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而"不用"使用对象来调用(注意:是"不用"而不是"不能")

    • 具有以下常用功能:

    • 给数组赋值:通过fill方法。

    • 对数组排序:通过sort方法,按升序。

      Arrays.sort(a);
      System.out.println(Arrays.toString(a));
    • 比较数组:通过equals方法比较数组中元素值是否相等。

    • 查找数组元素: 通过binarySearch方法能对排序好的数组进行二分查找法操作。

package com.base;
import java.util.Arrays;
public class Demo10_Arrays {
   public static void main(String[] args) {
       int[] a = {1, 2, 3, 4, 9090, 31231, 543, 21, 3, 23};
       System.out.println(a); // 数组对象的hashcode [I@4554617c
       //打印数组元素Arrays.tostring
       System.out.println(Arrays.toString(a));
       printArray(a);
  }
//自己编写打印数组的方法
   public static void printArray(int[] a) {
       for (int i = 0; i < a.length; i++) {
           if (i == 0) {
               System.out.print("[");
          }
           if (i == a.length - 1) {
               System.out.print(a[i] + "]");
          } else {
               System.out.print(a[i] + ", ");
          }
      }
  }
}

冒泡排序

  1. 冒泡排序无疑是最为出名的排序算法之一, 总共有八大排序!

  2. 冒泡的代码还是相当简单的,两层循环,外层冒泡轮数,里层依次比较,江湖中人人尽皆知。

  3. 我们看到嵌套循环,应该立马就可以得出这个算法的时间复杂度为0(n2)。

    import java.util.Arrays;
    //1. 比较数组中,两个相邻的元素,如果第一个数比第二个数大,我们就交换他们的位置
    //2. 每一次比较,都会产生出一个最大,或者最小的数字;
    //3. 下一轮则可以少一次排序!
    //4. 依次循环,直到结束!
    public class Demo11 {
       public static void main(String[] args) {
           int[] a = {1, 4, 5, 6, 72, 2, 2, 2, 25, 6, 7};
           int[] sort = sort(a); //调用完我们自己写的排序方法以后,返回一个排序后的数组
           System.out.println(Arrays.toString(sort));
      }
       public static int[] sort(int[] array) {
           //临时变量
           int temp = 0;
           //外层循环,判断我们这个要走多少次;
          for (int i = 0; i < array.length - 1; i++) {
               Boolean flag = false;
               //内层循环,比价判断两个数,如果第一个数,比第二个数大,则交换位置
               for (int j = 0; j < array.length - 1 - i; j++) {
                   if (array[j + 1] > array[j]) {
                       temp = array[j];
                       array[j] = array[j + 1];
                       array[j + 1] = temp;
                       flag = true;
                  }
              }
               if (flag == false){
                   break;
              }
          }
           return array;
      }
    }

稀疏数组介绍

  1. 当一个数组中大部分元素为0,或者为同一-值的数组时,可以使用稀疏数组来保存该数组。

  2. 稀疏数组的处理方式是:

    • 记录数组一共有几行几列,有多少个不同值

    • 把具有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模

public class Demo12_Sparse {
   public static void main(String[] args) {
       //创建一个元素的二维数组 11*11 0:没有棋子 1: 黑棋   2: 白棋
       int chessArry1[][] = new int[11][11];
       chessArry1[1][2] = 1;
       chessArry1[2][3] = 2;
       for (int [] row : chessArry1) {
           for ( int data : row) {
               System.out.printf("%d\t", data);
          }
           System.out.println();
      }
       int[][] paraseArr =  transformSparseArr(chessArry1);
       transformArry(paraseArr);
  }
   //二维数组 转 稀疏数组
   public static int[][] transformSparseArr( int[][] arry) {
       int sum =0;  // 有效值的个数
       int rowSize = 0;
       //1、计算出有效的个数
       for (int[] row :arry) {
           for ( int data :row) {
               rowSize = row.length;
               if (data != 0) {
                   sum++;
              }
          }
      }
       //创建稀疏数组 并给稀疏数组赋值
       int [][] sparseArr= new int[sum+1][3];
       sparseArr [0][0] = arry.length;
       sparseArr [0][1] = rowSize;
       sparseArr [0][2] = sum;
       //count 计数器 计算放入的有效个数 即第几个非零数据
       int count = 0;
       for (int i = 0; i < arry.length; i++) {
           for (int j = 0; j < rowSize ; j++) {
               if (arry[i][j] != 0) {
                   count++;
                   sparseArr[count][0] = i;
                   sparseArr[count][1] = j;
                   sparseArr[count][2] = arry[i][j];
              }
          }
      }
       // 输出稀疏数组形式
       System.out.println("===========稀疏数组============");
       for (int i = 0; i < sparseArr.length; i++) {
           // %d 占位符 \t 制表符 \n 换行
           System.out.printf("%d\t%d\t%d\t\n", sparseArr[i][0],sparseArr[i][1],sparseArr[i][2]);
      }
       System.out.println();
       return sparseArr;
  }
   // 稀疏数组 转化为 二维数组
   public static int[][] transformArry(int[][] parseArr) {
       int row = parseArr[0][0]; //得到行
       int col = parseArr[0][1]; //得到列
       //数组恢复 并赋值
       int[][] arry = new int[row][col];
       for (int i = 1 ; i < parseArr.length; i
java特性和优势

简单性、面向对象、可移植性、高能性、分布式、动态性、多线程、安全性、健壮性。

Java基本语法

标识符注意点

  1. 所有的标识符都应该以字母(A-Z 或者a-z) ,美元符($)、或者下划线( )开始

  2. 首字符之后可以是字母(A-Z 或者a-z) ,美元符($) 、下划线(或数字的任何字符组合

  3. 不能使用关键字作为变量名或方法名。

  4. 标识符是大小写敏感的

  5. 可以使用中文命名,但是一般不建议这样去使用,也不建议使用拼音,很Low

  6. 数字字母下滑线,数字不能开头

数据类型

强类型语言

要求变量的使用要严格符合规定,所有变量都必须先定义后才能使用

弱类型语言

  1. Java的数据类型分为两大类 基本类型(primitive type) 引用类型(reference type)

  2. 浮点数拓展?银行业务怎么 表示?钱(BigDecimal数学工具类) //float(double) 有限 离散 舍入误差,大约接近但不等于

  3.  

什么是字节

  1. 位(bit) :是计算机内部数据储存的最小单位,11001100是一 个八位二进制数。

  2. 字节(byte) :是计算机中数据处理的基本单位,习惯上用大写B来表示,

  3. 1B (byte,字节) = 8bit (位)

  4. 字符:是指计算机中使用的字母、数字、字和符号

类型转换

由于Java是强类型语言,所以要进行有些运算的时候的,需要用到类型转换。

  • 低-------------------------------> 高 byte, short,char-> int -> long-> float -> double

  • 运算中,不同类型的数据先转化为同一类型,然后进行运算。

    • 强制类型转换

      高-->低

    • 自动类型转换

      低-->高

注意点:

  1. 不能对布尔值进行转换

  2. 不能把对象类型转换为不相干的类型

  3. 在把高容量转换到低容量的时候,强制转换

  4. 转换的时候可能存在内存溢出,或者精度问题! 

变量

  1. 变量是什么:就是可以变化的量!

  2. Java是一种强类型语言,每个变量都必须声明其类型。

  3. Java变量是程序中最基本的存储单元,其要素包括变量名,变量类型和作用域。

    type varName [=value] [{,varName[=value]}] ;
    //数据类型变量名 =值;可以使用逗号隔开来声明多个同类型变量。
  1. 注意事项:

  • 每个变量都有类型,类型可以是基本类型,也可以是引用类型。

  • 变量名必须是合法的标识符。

  • 变量声明是一条完整的语句,因此每一个声明都必须以分号结束

public class demo01 {
   //类变量static
   static double salary = 2500;
   //属性:变量
   //实例变量:从属于对象;如果不自行初始化,这个类型的默认值 0.0
   //布尔值:默认是false
   //除了基本类型,其余的默认值都是nulL;
   String name;
   int age;
   //main方法
   public static void main(String[] args) {
       //局部变量;必须声明和初始化值
       int i=10;
       System.out. println(i);
       //变量类型变量名字 = new Demo08();
       demo01 demo01 = new demo01();
       System. out. println(demo01.age);
       System. out . println(demo01. name);
       //类变量static
       System.out. println(salary);
  }
   //其他方法
   public void add(){
  }
}

常量

常量(Constant): 初始化(initialize)后不能再改变值!不会变动的值。

所谓常量可以理解成一种特殊的变量,它的值被设定后,在程序运行过程中不允许被改变.

final常量名=值;
final double PI=3.14;

常量名一般使用大写字符。

变量的命名规范

  1. 所有变量、方法、类名:见名知义

  2. 类成员变量:首字母小写和驼峰原则: monthSalary

  3. 局部变量:首字母小写和驼峰原则

  4. 常量:大写字母和下划线: MAX_ VALUE

  5. 类名:首字母大写和驼峰原则: Man, GoodMan

  6. 方法名:首字母小写和驼峰原则: run(), runRun()

  7. 类成员变量:首字母小写和驼峰原则: monthSalary

  8. 局部变量:首字母小写和驼峰原则

  9. 常量:大写字母和下划线: MAX_ VALUE

  10. 类名:首字母大写和驼峰原则: Man, GoodMan

  11. 方法名:首字母小写和驼峰原则: run(), runRun()

运算法

  1. 算术运算符

    short+bety+long+int-->存在long为long,否则结果为int

    存在double则为double

  1. a++、++a

    int b = a++; //执行完这行代码后, 先给b赋值,再自增
    int c = ++a; ////执行完这行代码前, 先自增,再给b赋值
  2. 位运算符

    <<、>>效率极快

  3. 字符串连接符+

    System . out .println("" +a+b);//""先和a拼接,在和b拼接,a+b不进行算术运算
    System . out. println(a+b+"");//a+b先进行算术运算,在和""拼接

包机制

  1. 为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间。

  2. 包语句的语法格式为:

    package pkg1[. pkg2[. pk...]];
  3. 一般利用公司域名倒置作为包名;

  4. 为了能够使用某一个包的成员,我们需要在Java程序中明确导入该包。使用"import"语句可 完成此功能

    import package1[. package..].(classname |*);

Java Doc

  1. javadoc命令是用来生成自己API文档的

  2. 参数信息

    • @author作者名

    • @version 版本号

    • @since 指明需要最早使用的jdk版本

    • @param参数名

    • @return 返回值情况

    • @throws 异常抛出情况

Java流程控制

Scanner对象

  1. 之前我们学的基本语法中我们并没有实现程序和人的交互,但是Java给我们提供了这样一个工具类,我们可以获取用户的输入。

  2. java.util.Scanner 是Java5的新特征,我们可以通过Scanner类来获取用户的输入。

  3. 基本语法:

    Scanner S = new Scanner( System. in);
  1. 通过Scanner类的next()与nextLine()方法获取输入的字符串,在读取前我们一般需要使用hasNext()与hasNextLine()判断是否还有输入的数据。

    • next()和hasNext()

      public class Demo02_Scanner {
         public static void main(String[] args) {
             //创建一个扫描器对象,用于接收键盘数据
             Scanner scanner = new Scanner(System.in);
             System.out.println("使用next方式接收: ");
             //判断用户有没有输入字符串
             if (scanner.hasNext()){
                 //使用next方式接收
                 String str = scanner.next();//程序会等待输入内容,不输入会卡在这里
                 System.out.println("输出的内容为: "+str);
            }
             //凡是属于IO流的类如果不关闭会一直占用资源.要养成好习惯用完就关掉
             scanner.close();
        }
      }
    • nextLine()和hasNextLine()

      public class Demo02_Scanner {
         public static void main(String[] args) {
             Scanner scanner = new Scanner(System.in);
             System.out.println("使用nextLine方式接收: ");
             //判断是否还有输入
             if (scanner.hasNextLine()) {
                 String str = scanner.nextLine();
                 System.out.println("输出的内容为: " + str);
            }
             scanner.close();
        }
      }
    • next():

      • 一定要读取到有效字符后才可以结束输入。

      • 对输入有效字符之前遇到的空白,next() 方法会自动将其去掉。

      • 只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。

      • next() 不能得到带有空格的字符串。

    • nextLine():

      • 以Enter为结束符,也就是说nextLine()方法返回的是输入回车之前的所有字符。

      • 可以获得空白。

  2. 使用语法

    public class Demo02_Scanner {
       public static void main(String[] args) {
    Scanner scanner = new Scanner(System. in);
       System.out.println("请输入数据: ");
    String str = scanner.nextLine( );
    System.out .println( "输出的内容为: "+str);
    scanner.close();
      }
    }
  1. 其他hasNextInt()和hasNextFloat()

    public class Demo03_Scanner {
       public static void main(String[] args) {
           Scanner scanner = new Scanner(System.in);
           //从键盘接收数据
           int i = 0;
           float f = 0.0f;
           System.out.println("请输入整数: ");
           if (scanner.hasNextInt()) {
               i = scanner.nextInt();
               System.out.println("整数数据: " + i);
          } else {
               System.out.println("输入的不是整数数据! ");
          }
           System.out.println("请输入小数: ");
           if (scanner.hasNextFloat()) {
               f = scanner.nextFloat();
               System.out.println("小数数据: " + f);
          } else {
               System.out.println("输入的不是小数数据! ");
          }
           scanner.close();
      }
    }
  1. 输入多个数字,并求其总和与平均数

import java.util.Scanner;

public class Demo04_Scanner {
   public static void main(String[] args) {
       //我们可以输入多个数字,并求其总和与平均数,每输入一个数字用回车确认,通过输入非数字来结束输入并输出执行结果:
       Scanner scanner = new Scanner(System.in);
       double sum = 0;
       int m = 0;
       //通过循环判断是否还有输入,并在里面对每-次进行求和和统计
       while (scanner.hasNextDouble()){
           double x = scanner.nextDouble();
           m=m+1; //m++
           sum=sum+x;
           System.out.println("你输入了第"+m+"个数据,然后当前结果sum=" +sum) ;
      }
       System.out.println(m + "个数的和为" + sum);
       System.out.println(m +"个数的平均值是" + (sum / m));
       scanner.close();
  }
}

switch多选择结构

  1. 多选择结构还有一个实现方式就是switch case语句。

  2. switch case语句判断一个变量与一系列值中某个值是否相等,每个值称为一个分支。

  3. switch 语句中的变量类型可以是:

    • byte、short, int 或者char.

    • 从JavaSE7开始,switch支持字符串String类型了

      • 字符的本质是数字

      • java文件

      public class Demo05_Switch {
         public static void main(String[] args) {
             String name = "狂神";
             switch (name){
                 case "秦疆":
                     System.out.println("秦疆");
                     break;
                 case "狂神":
                      System.out.println("狂神");
                      break;
                 default :
                     System.out.println("弄啥嘞! ");
            }
        }
      }
      • class文件(hashCode())

        //
        // Source code recreated from a .class file by IntelliJ IDEA
        // (powered by Fernflower decompiler)
        //

        package com.base;

        public class Demo05_Switch {
          public Demo05_Switch() {
          }

          public static void main(String[] args) {
              String name = "狂神";
              byte var3 = -1;
              switch(name.hashCode()) {
              case 941788:
                  if (name.equals("狂神")) {
                      var3 = 1;
                  }
                  break;
              case 997472:
                  if (name.equals("秦疆")) {
                      var3 = 0;
                  }
              }

              switch(var3) {
              case 0:
                  System.out.println("秦疆");
                  break;
              case 1:
                  System.out.println("狂神");
                  break;
              default:
                  System.out.println("弄啥嘞! ");
              }

          }
        }
    • 同时case标签必须为字符串常量或字面量。

增强for循环

  1. 这里我们先只是见一面,做个了解,之后数组我们重点使用

  2. Java5引入了一种主要用于数组或集合的增强型for循环。

  3. Java增强for循环语法格式如下:

    for(声明语句:表达式)
    {
    //代码句子
    }
    • 声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循 环语句块,其值与此时数组元素的值相等。

    • 表达式:表达式是要访问的数组名,或者是返回值为数组的方法。

public class Demo06_Foreach {
   public static void main(String[] args) {
       int[] numbers = {10,20,30,40,50}; //定义了一个数组
       //遍历数组的元素
       for (int x: numbers){
           System.out.println(x);
      }
  }
}

break continue

  1. break在任何循环语句的主体部分,均可用break控制循环的流程。break用于强行退出循环,不执行循环中剩余的语句。(break语句也在switch语句中使用)

  2. continue语句用在循环语句体中,用于终止某次循环过程,即跳过循环体中尚未执行的语句,接着进行下一次是否执行循环的判定。

  3. 关于goto关键字 goto关键字很早就在程序设计语言中出现。尽管goto仍是Java的- 个保留字,但并未在语言中得到正式使用; Java没有goto。然而,在break和continue这两个关键字的身上,我们仍然能看出一些goto的影子——带标签的break和continue.

    • "标签" 是指后面跟一个冒号的标识符,例如: label:

    • 对Java来说唯一 用到标签的地方是在循环语句之前。 而在循环之前设置标签的唯一理由是:我们希望在其中嵌套另一个循环,由于break和continue关键字通常只中断当前循环,但若随同标签使用,它们就会中断到存在标签的地方。

public class Demo07_Label {
   public static void main(String[] args) {
       //打101- 150之问所有的质数
       int count = 0;
       //不建议使用!
       outer:for (int i = 101;i < 150;i++){
           for (int j = 2; j < i/2;j++){
               if (i %j== 0){
                   continue outer;
              }
          }
           System.out.print(i+" ");
      }
  }
}
方法

何谓方法?

  1. System.out.println(), 那么它是什么呢?

  2. Java方法是语句的集合,它们在一起执行一个功能。

    • 方法是解决一类问题的步骤的有序组合

    • 方法包含于类或对象中

    • 方法在程序中被创建, 在其他地方被引用

  3. 设计方法的原则:方法的本意是功能块,就是实现某个功能的语句块的集合。我们设计方法的时候,最好保持方法的原子性,就是一个方法只完成1个功能,这样利于我们后期的扩展

  1. 回顾:方法的命名规则?

方法的定义

  1. Java的方法类似于其它语言的函数,是-段用来完成特定功能的代码片段,一般情况下,定义一个方法包含以下语法:

    • 方法包含一个方法头和一个方法体。下面是一个方法的所有部分:

    • 修饰符:修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。

    • 返回值类型:方法可能会返回值。returnValueType 是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType 是关键字void。

    • 方法名:是方法的实际名称。方法名和参数表共同构成方法签名。

    • 参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。

      • 形式参数:在方法被调用时用于接收外界输入的数据。

      • 实参:调用方法时实际传给方法的数据。

    • 方法体:方法体包含具体的语句,定义该方法的功能。

      修饰符 返回值 类型 方法名(参数类型参数名){
      方法体
      return返回值;
      }

方法调用

  1. 调用方法:对象名.方法名(实参列表)

  2. Java支持两种调用方法的方式,根据方法是否返回值来选择。

    • 当方法返回一个值的时候,方法调用通常被当做一个值。例如: int larger = max(30,40);

    • 如果方法返回值是void,方法调用一定是一条语句。 System. out. println( "Hello, kuangshen!");

  3. 课后拓展了解:值传递(Java)和引用传递

方法的重载

  1. 重载就是在一个类中,有相同的函数名称,但形参不同的函数。

  2. 方法的重载的规则:

    • 方法名称必须相同。

    • 参数列表必须不同(个数不同、或类型不同、参数排列顺序不同等)。

    • 方法的返回类型可以相同也可以不相同。

    • 仅仅返回类型不同不足以成为方法的重载。

  3. 实现理论:

    方法名称相同时,编译器会根据调用方法的参数个数、参数类型等去逐个匹配,以选择对应的方法,如果匹配失败,则编译器报错。

命令行传参

有时候你希望运行一个程序时候再传递给它消息。这要靠传递命令行参数给main()函数实现。

public class CommandLine {
public static void main(String args[]){
for(int i=0; i<args.length; i++){
System. out. println("args["+ i + "]:"+ args[i]);
}
}
}

可变参数

  1. JDK 1.5开始,Java支持传递同类型的可变参数(不定项)给一个方法。

  2. 在方法声明中,在指定参数类型后加一个省略号(..)。

  3. 一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它之前声明。

public class Demo08 {
   public static void main(String args[]) {
       //调用可变参数的方法
       printMax(15,22.0,36,25.3);
       printMax(new double[]{1, 2, 3});//本质为数组

  }
   public static void printMax(double... numbers) {
       if (numbers.length == 0) {
           System.out.println("No argument passed");
           return;
      }
       double result = numbers[0];
       //排序!
       for (int i = 1; i < numbers.length; i++) {
           if (numbers[i] > result) {
               result = numbers[i];
          }
      }
       System.out.println("The max value is " + result);
  }
}

递归(能不用就不用)

  1. 递归就是: A方法调用A方法!就是自己调用自己

  2. 利用递归可以用简单的程序来解决一些复杂的问题。 它通常把一个大型复杂的问题层层转化为-个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。

  3. 递归结构包括两个部分:

    • 递归头:什么时候不调用自身方法。如果没有头,将陷入死循环。

    • 递归体:什么时候需要调用自身方法。

Java数组

数组的定义

  1. 数组是相同类型数据的有序集合.

  2. 数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。

  3. 其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们.

数组声明创建

  1. 首先必须声明数组变量,才能在程序中使用数组。下面是声明数组变量的语法:

    dataType[] arrayRefVar; // 首选的方法

    dataType arrayRefVar[]; // 效果相同,但不是首选方法
  2. Java语言使用new操作符来创建数组,语法如下:

    dataType[] arrayRefVar = new dataType[arraySize] ;
  3. 数组的元素是通过索引访问的,数组索引从0开始。

    • 获取数组长度:arrays . length

int[] nums; //1.声明-一个数组
nums = new int[10]; //2. 创建一个数组
nums[0] = 1;//3.给数组元素中赋值

三种初始化

  1. 静态初始化

    int[] a = {1,2,3};
    Man[] mans = {new Man(1,1) , new Man(2,2)};
  2. 动态初始化

    int[] a = new int[2]; 
    a[0]=1;
    a[1]=2;
  3. 数组的默认初始化

    数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。

数组的四个基本特点

  1. 其长度是确定的。数组一旦被创建,它的大小就是不可以改变的。

  2. 其元素必须是相同类型,不允许出现混合类型。

  3. 数组中的元素可以是任何数据类型,包括基本类型和引用类型。

  4. 数组变量属引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量。

  5. 数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的。

小结:

  1. 数组是相同数据类型(数据类型可以为任意类型)的有序集合

  2. 数组也是对象。数组元素相当于对象的成员变量

  3. 数组长度的确定的,不可变的。如果越界,则报: ArrayIndexOutofBounds

数组使用

  1. For-Each循环

    public class Demo09_Array {
       public static void main(String[] args) {
           int[] arrays = {1,2,3,4,5};
           //JDK1.5,没有下标
           for (int array : arrays) {
               System.out.println(array);
          }
      }
    }
  2. 数组作方法入参

    public class Demo09_Array {
       public static void main(String[] args) {
           int[] arrays = {1,2,3,4,5};
           printArray(arrays);
      }
       //打印数组元素
       public static void printArray(int[] arrays){
           for (int i = 0; i < arrays.length; i++) {
               System.out.print(arrays[i]+" ");
          }
      }
    }
  3. 数组作返回值

    public class Demo09_Array {
       public static void main(String[] args) {
           int[] arrays = {1,2,3,4,5};
           int[] reverse = reverse( arrays);
           printArray(reverse);
      }
       //反转数组
       public static int[] reverse(int[] arrays){
           int[] result = new int [arrays.length];
           //反转的操作
           for (int i = 0,j=result.length-1; i < arrays.length; i++,j--) {
               result[j] = arrays[i];
          }
           return result;
      }
       //打印数组元素
       public static void printArray(int[] arrays){
           for (int i = 0; i < arrays.length; i++) {
               System.out.print(arrays[i]+" ");
          }
      }
    }

多维数组

  1. 多维数组可以看成是数组的数组,比如维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组。

  2. 二维数组

    int a[][] = new int[2][5];
    • 解析:二维数组a可以看成一个两行三列的数组。

  3. 思考:多维数组的使用?

Arrays类

  1. 数组的工具类java.util.Arrays

  2. 由于数组对象本身并没有什么方法可以供我们调用,但API中提供了-一个工具类Arrays供我们使用,从而可以对数据对象进行一些基本的操作。

    查看JDK帮助文档

  1. Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而"不用"使用对象来调用(注意:是"不用"而不是"不能")

    • 具有以下常用功能:

    • 给数组赋值:通过fill方法。

    • 对数组排序:通过sort方法,按升序。

      Arrays.sort(a);
      System.out.println(Arrays.toString(a));
    • 比较数组:通过equals方法比较数组中元素值是否相等。

    • 查找数组元素: 通过binarySearch方法能对排序好的数组进行二分查找法操作。

package com.base;
import java.util.Arrays;
public class Demo10_Arrays {
   public static void main(String[] args) {
       int[] a = {1, 2, 3, 4, 9090, 31231, 543, 21, 3, 23};
       System.out.println(a); // 数组对象的hashcode [I@4554617c
       //打印数组元素Arrays.tostring
       System.out.println(Arrays.toString(a));
       printArray(a);
  }
//自己编写打印数组的方法
   public static void printArray(int[] a) {
       for (int i = 0; i < a.length; i++) {
           if (i == 0) {
               System.out.print("[");
          }
           if (i == a.length - 1) {
               System.out.print(a[i] + "]");
          } else {
               System.out.print(a[i] + ", ");
          }
      }
  }
}

冒泡排序

  1. 冒泡排序无疑是最为出名的排序算法之一, 总共有八大排序!

  2. 冒泡的代码还是相当简单的,两层循环,外层冒泡轮数,里层依次比较,江湖中人人尽皆知。

  3. 我们看到嵌套循环,应该立马就可以得出这个算法的时间复杂度为0(n2)。

    import java.util.Arrays;
    //1. 比较数组中,两个相邻的元素,如果第一个数比第二个数大,我们就交换他们的位置
    //2. 每一次比较,都会产生出一个最大,或者最小的数字;
    //3. 下一轮则可以少一次排序!
    //4. 依次循环,直到结束!
    public class Demo11 {
       public static void main(String[] args) {
           int[] a = {1, 4, 5, 6, 72, 2, 2, 2, 25, 6, 7};
           int[] sort = sort(a); //调用完我们自己写的排序方法以后,返回一个排序后的数组
           System.out.println(Arrays.toString(sort));
      }
       public static int[] sort(int[] array) {
           //临时变量
           int temp = 0;
           //外层循环,判断我们这个要走多少次;
          for (int i = 0; i < array.length - 1; i++) {
               Boolean flag = false;
               //内层循环,比价判断两个数,如果第一个数,比第二个数大,则交换位置
               for (int j = 0; j < array.length - 1 - i; j++) {
                   if (array[j + 1] > array[j]) {
                       temp = array[j];
                       array[j] = array[j + 1];
                       array[j + 1] = temp;
                       flag = true;
                  }
              }
               if (flag == false){
                   break;
              }
          }
           return array;
      }
    }

稀疏数组介绍

  1. 当一个数组中大部分元素为0,或者为同一-值的数组时,可以使用稀疏数组来保存该数组。

  2. 稀疏数组的处理方式是:

    • 记录数组一共有几行几列,有多少个不同值

    • 把具有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模

public class Demo12_Sparse {
   public static void main(String[] args) {
       //创建一个元素的二维数组 11*11 0:没有棋子 1: 黑棋   2: 白棋
       int chessArry1[][] = new int[11][11];
       chessArry1[1][2] = 1;
       chessArry1[2][3] = 2;
       for (int [] row : chessArry1) {
           for ( int data : row) {
               System.out.printf("%d\t", data);
          }
           System.out.println();
      }
       int[][] paraseArr =  transformSparseArr(chessArry1);
       transformArry(paraseArr);
  }
   //二维数组 转 稀疏数组
   public static int[][] transformSparseArr( int[][] arry) {
       int sum =0;  // 有效值的个数
       int rowSize = 0;
       //1、计算出有效的个数
       for (int[] row :arry) {
           for ( int data :row) {
               rowSize = row.length;
               if (data != 0) {
                   sum++;
              }
          }
      }
       //创建稀疏数组 并给稀疏数组赋值
       int [][] sparseArr= new int[sum+1][3];
       sparseArr [0][0] = arry.length;
       sparseArr [0][1] = rowSize;
       sparseArr [0][2] = sum;
       //count 计数器 计算放入的有效个数 即第几个非零数据
       int count = 0;
       for (int i = 0; i < arry.length; i++) {
           for (int j = 0; j < rowSize ; j++) {
               if (arry[i][j] != 0) {
                   count++;
                   sparseArr[count][0] = i;
                   sparseArr[count][1] = j;
                   sparseArr[count][2] = arry[i][j];
              }
          }
      }
       // 输出稀疏数组形式
       System.out.println("===========稀疏数组============");
       for (int i = 0; i < sparseArr.length; i++) {
           // %d 占位符 \t 制表符 \n 换行
           System.out.printf("%d\t%d\t%d\t\n", sparseArr[i][0],sparseArr[i][1],sparseArr[i][2]);
      }
       System.out.println();
       return sparseArr;
  }
   // 稀疏数组 转化为 二维数组
   public static int[][] transformArry(int[][] parseArr) {
       int row = parseArr[0][0]; //得到行
       int col = parseArr[0][1]; //得到列
       //数组恢复 并赋值
       int[][] arry = new int[row][col];
       for (int i = 1 ; i < parseArr.length; i