java基础中(笔记)

方法

方法是用来完成特定功能的片段代码

 

 

结构

public 【修饰符】 int 【返回值类型】 add【方法名】(int 【参数类型】 a 【参数名】,int b){
int c=0; c=a+b;//方法体
   return c;//返回值
}
修饰符

定义该方法的访问类型

public,protected(受保护的访问修饰符),default(默认,仅当前包),private(仅当前类)

成员变量一般是private,为了让外界去修改对象的属性从而提供了get和set方法,这也是一种封装

protected(当前包以及其他包继承该方法的子类):

子类与父类不在同一包中,子类实例可以访问其从父类继承而来的 protected 方法,而不能访问父类实例的protected方法。

返回值类型

方法可能返回的值类型,如果为void则表示没有返回值,方法体已经完成了方法的功能

方法名

方法实际的名称

参数类型

参数的类型,由方法编写者定义,方法可以不包括任何参数

形式参数

方法编写阶段,参数类型和参数名构成了形式参数

实参

方法被调用是传递的真实数据就是实参

!可变参数

在指定的参数类型后加...表示可变参数,一个方法中只能有一个可变参数且位于最后一个参数

例子:

public class demo01 {
   //int... b中b就相当于一个数组
   public void put(int a,int... b){
       System.out.println(a);
       System.out.println(b[0]);
       System.out.println(b[1]);
       System.out.println(b[2]);
       System.out.println(b[3]);
  }
   //调用它
   public static void main(String[] args){
      demo01 demo01=new demo01();
      demo01.put(1,4,3,2,1);
  }
}
方法体

方法体就是该方法完成功能的代码片段

 

 

static(静态)

静态方法是随着类的加载而产生的,所以类或者对象可以直接调用静态方法,而非静态方法是随着对象创建而创建的,所以只能借助对象来调用

静态方法是类的方法,非静态方法是对象的方法

静态的成员变量与非静态的成员变量的区别

作用上的区别:

  1. 静态的成员变量的作用共享一个数据给所有的对象使用。

  2. 非静态的成员变量的作用是描述一类事物的公共属性。

数量与存储位置上的区别:

  1. 静态成员变量是存储方法区内存中,而且只会存在一份数据。

  2. 非静态的成员变量是存储在堆内存中,有n个对象就有n份数据。

生命周期的区别:

  1. 静态的成员变量数据是随着类的加载而存在,随着类文件的消失而消失。

  2. 非静态的成员数据是随着对象的创建而存在,随着 对象被垃圾回收器回收而消失。

static什么时候修饰一个方法

如果一个方法没有直接访问到非静态的成员时,那么就可以使用static修饰了。 一般用于工具类型的方法

静态方法不能访问非静态的成员?

静态方法只要存在有对象,那么也可以访问非静态的数据。只是不能直接访问而已。

因为静态方法是随着类的加载而产生的,所以类或者对象可以直接调用静态方法,而非静态方法是随着对象创建而创建的,所以只能借助对象来调用

static方法为什么只能调用static方法?

以为静态方法是和类一起加载到方法区的,先于对象的加载

 

 

重载

在同一类中有相同的名称的方法,但需传递的参数不同

规则
  1. 方法名一致

  2. 参数列表必须不一样

  3. 返回值类型可以相同也可以不同,返回值类型不同时,参数列表一定不能相同。

    仅仅返回值不同不足以称之为方法的重载

实现理论

方法名称相同时,编译器会根据调用方法的参数个数,参数类型等逐一匹配来选择对应方法,如果匹配失败则爆红

 

 

递归!

递归就是一个方法中,自己调用自己

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

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

 public static void main(String[] args){
       demo01 demo=new demo01();
       int result = demo.digui(5);
       System.out.println(result);
  }

       //实现阶乘
       public int digui(int a){
           //递归头
          if (a==1) {
               return 1;
          }else {
           //递归体
              return a*digui(a-1);
          }
      }

 

 

 

 

数组

定义:

数组是相同类型数据的长度固定的有序集合,每个数组元素可以通过其下标访问

 

数组可以看成对象它们都是引用类型,数组的元素可以看成成员变量

数组的申明创建

申明

数组类型 +数组名;

//dataType[] arrayName;  dataType arrayName[];  
int[] name;   int name[];  
创建
//new出数组
dataType[] arrayName=new dataType[arraySize];
int[] name=new int[4];//默认数组元素是0;

//数组索引从0开始
int[] name={1,2,3,4};
System.out.println(name[0]==1);//返回的true
//获取数组长度
name.length;
数组的初始化
       //静态初始化
int[] name={1,2,3,4};//基本类型
Man[] mans={new man(1,1),new man(2,2)}//引用类型
      //动态初始化
int[] name=new int[4];
       name[0]=1;
       name[1]=2;
       name[2]=3;
       name[3]=4;
数组和对象的内存分析

堆: 存放new的对象和数组,可以被所有线程共享,不会存放别的对象引用 栈:存放基本变量类型(包含其具体的值),引用对象的变量(包含其在堆里的具体地址)。 方法区 :可以被所有线程共享,包含了所有的class和static变量

写个列子:数组创建时栈堆工作流程

如果把数组理解成对象:

对象实体本身创建在堆中,它的引用变量创建在栈中

这里的array是对象实体的引用变量,而并非对象实体本身

对象的引用变量可以理解为指针,它存放的是对象实体的引用

//执行int[] array=new int[3];可以拆成下列几步
//1.申明整型数组array,此时栈中出现了array数组,但堆还没被创建
int[] array=null;
//2.创建数组,堆中创建array数组,栈中的array指向堆中的array数组
array=new int[3]
//3,给数组元素赋值,完成后堆中数组元素将被赋值,栈中也会存在这些值
   array[0]=1;
   array[1]=2;
   array[2]=3;

 

数组的使用

普通for循环

可以运用下标对数组进行精细的操作

for-each循环

不能运用下标,但可以很方便的打印数组

数组做方法入参
数组做方法的返回值

 

多维数组

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

二维数组
int a[][]=new int[2][5] 
   
   //例子
   int[4][2] array={{1,1},{2,2},{3,3},{4,4}}
//三维
int[4][2][2] array={{{1,1},{1,2}},{{2,1},{2,2}},{{3,1},{3,2}},{{4,1},{4,2}}}
array[0]=={{1,1},{1,2}};array[0][0][0]==1;
       array[1]=={{2,1},{2,2}};
       array[2]=={{3,1},{3,2}};
       array[3]=={{4,1},{4,2}};

 

数组的实际应用

Arrays工具类

其所有方法都是static修饰,可以直接使用类名调用

直接打印数组:toString

给数组赋值:fill方法

int[] a={1,2,3,4};
Arrays.fill(a,0);//数组里面所有元素填充成0
[0,0,0,0]//打印结果
Arrays.fill(a,1,2,0);//填充[1,2)半开半闭区间的索引为0
[1,0,3,4]//打印结果

对数组排序:sort方法,默认升序

比较数组:equals

查找数组元素:binarySearch方法能对数组进行二分法查找

 

冒泡排序

这里就简单认识一下八大排序算法之一的冒泡排序,其他排序自己再去了解吧

冒泡排序相对简单,两层循环,外层冒泡轮数,里层依次比较

原始模版
public static int[] sort(int[] array){
int temp=0;
//外层循环,判断要执行多少次(内层循环执行完一次会得一个到内层的极值)
for(int i=0;i<array.length-1;i++){
//内层循环,由if决定排序方式,这里是后一个数比前一个数大则交换位置(故大的会排在前面)
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;
}
}
}
return array;
}
优化冒泡排序

这只是一种思路,不见得优化的了多少

    public static int[] sort2(int[] array){
int temp=0;
//外层循环,判断要执行多少次(内层循环执行完一次会得一个到内层的极值)
for(int i=0;i<array.length-1;i++){
Boolean flag=false;
//内层循环,由if决定排序方式,这里是后一个数比前一个数大则交换位置(故大的会排在前面)
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!=true){
break;
}
}
}
return array;
}

 

稀疏数组

场景:五子棋游戏,以1为白棋,2为黑棋,0为空地,这样没有记录意义0就占用了很多内存

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

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

处理思路
  • 记录数组有几行几列,有多少不同的值

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

如下

0 0 0 0 0 0 0 0 0 33 0 0 0 0 53 0 0 0 0 21 0 0 0 0 0 0 0 0 14 0 0 0 0 0 33 0 0 0 0 0 0 0 0 0 0 0 0 0

会被记录成

	行(row)|列(col)|值(value)		
[0] 6 | 5 | 5 //这里行列是整个行列(全是0不能忽略),值是不同数的个数
------------------------------
[1] 1 | 1 | 33 //这里行列是值在全部行列的位置(从0开始计算)
[2] 1 | 6 | 53
[3] 2 | 3 | 21
[4] 3 | 4 | 14
[5] 4 | 2 | 33
代码实现

转换稀疏数组以及还原


public class SparseArray {
public static void main(String[] args) {

// 1.模拟出来棋盘数据,使用二维数组
int num = 11;
int[][] array = new int[num][num];
array[1][2] = 1;
array[2][4] = 2;

// 打印棋盘查看效果
for (int[] row : array) {
for (int val : row) {
System.out.printf("%d\t", val);
}
System.out.println();
}

// 需要把如上的二维数组中有效数据压缩至稀疏数组中去
// 计算二维数组中有效数据
int sum = 0;
for (int i = 0; i < num; i++) {
for (int j = 0; j < num; j++) {
if (array[i][j] != 0) {
sum++;
}
}
}

// 定义稀疏数组
int[][] sparseArray = new int[sum + 1][3];
// 行
sparseArray[0][0] = 11;
// 列
sparseArray[0][1] = 11;
// 有效数据个数
sparseArray[0][2] = sum;

// 把有效数据存放至稀疏数组中去
int count = 0;
// 行的索引
for (int i = 0; i < num; i++) {
// 列的索引
for (int j = 0; j < num; j++) {
// 判断是否是有效数据
if (array[i][j] != 0) {
count++;
sparseArray[count][0] = i;
sparseArray[count][1] = j;
sparseArray[count][2] = array[i][j];
}
}
}

// 打印稀疏数组
for (int[] ints : sparseArray) {
// System.out.printf("%d,%d,%d\t", ints[0], ints[1], ints[2]);
System.out.println(ints[0] + " " + ints[1] + " " + ints[2]);
}


// 把稀疏数组转原始二维数组(面试题)
int[][] oldArray = new int[sparseArray[0][0]][sparseArray[0][1]];

for (int i = 1; i <= count; i++) {
oldArray[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2];
}

System.out.println("========================================");

// 原始二维数组棋盘
for (int[] row : oldArray) {
for (int val : row) {
System.out.printf("%d\t", val);
}
System.out.println();
}
}
}
 

 

 

posted @ 2023-07-30 17:38  haohao2036  阅读(6)  评论(0编辑  收藏  举报