Java 学习笔记 二
数组 数组(array)是一种用于存储多个相同类型数据的存储模型
格式 初始化 JAVA中的数组必须先初始化,然后才能使用
初始化:为数据中的数组元素分配内存空间,并为每个元素赋值
动态初始化 动态初始化:初始化时只指定数据长度,由系统为数组分配初始值
1 数据类型[] 变量名 = new 数据类型[数组长度];
静态初始化 静态初始化:初始化时指定每个元素的初始值,由系统决定数组长度
1 2 3 数据类型[] 变量名 = new 数据类型[数组长度]{数据1 ,数据2 ,数据3 ,......}; 数据类型[] 变量名 = {数据1 ,数据2 ,数据3 ,......};
数组元素访问 每一个存储到数组的元素,都会自动的拥有一个编号,从0开始。 这个自动编号称为数组索引(index),可以通过数组的索引访问到数组中的元素。
内存分配 内存是计算机中的重要原件,临时存储区域,作用是运行程序。 我们编写的程序是存放在硬盘中的,在硬盘中的程序是不会运行的。 必须放进内存中才能运行,运行完毕后会清空内存。 Java 虚拟机要运行程序,必须要对内存进行空间的分配和管理。
Java程序在运行时,需要在内存中分配空间。为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。
目前我们只需要记住两个内存,分别是:栈内存和堆内存
单个数组 多个数组 相同地址 常见问题 索引越界 访问了数组中不存在的索引对应的元素,造成索引越界问题 程序运行后,将会抛出 ArrayIndexOutOfBoundsException 数组越界异常。在开发中,数组的越界异常是不能出现的,一旦出现了,就必须要修改我们编写的代码。
空指针异常 访问的数组已经不再指向堆内存的数据,造成空指针异常 arr = null 这行代码,意味着变量 arr 将不会再保存数组的内存地址,也就不允许再操作数组了,因此运行的时候会抛出 NullPointerException 空指针异常。 null:空值,引用数据类型的默认值,表示不指向任何有效对象
常见操作 遍历 最值问题 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class ArrayTest02 { public static void main (String[] args) { int [] arr = {12 , 45 , 98 , 73 , 60 }; int max = arr[0 ]; for (int x=1 ; x<arr.length; x++) { if (arr[x] > max) { max = arr[x]; } } System.out.println("max:" + max); } }
方法 方法(method)是将具有独立功能的代码块组织成为一个整体,使其具有特殊功能的代码集
注意:
方法必须先创建才可以使用,该过程称为方法定义 。 方法创建后并不是直接可以运行的,需要手动使用后,才执行,该过程称为方法调用 。 定义与调用 不带参数 定义 1 2 3 public static void 方法名 ( ) { }
调用 带参数 参数:由数据类型和变量名组成 → 数据类型 变量名
定义 1 2 3 4 5 6 public static void 方法名 (参数1 ) { 方法体; } public static void 方法名 (参数1 , 参数2 , 参数3. ..) { 方法体; }
调用 注意:
方法定义时,参数中的数据类型与变量名都不能缺少 ,缺少任意一个程序将报错 方法调用时,参数的数量与类型必须与方法定义中的设置相匹配 ,否则程序将报错 形参与实参 形参:方法定义中 的参数
实参:方法调用中 的参数
带返回值 定义 1 2 3 public static 数据类型 方法名 ( 参数 ) { return 数据 ; }
调用 1 2 方法名 ( 参数 ) ; 数据类型 变量名 = 方法名 ( 参数 ) ;
注意:
方法定义时 return 后面的返回值与方法定义上的数据类型要匹配 ,否则程序将报错 方法的返回值通常会使用变量接收 ,否则该返回值将无意义 注意事项 方法不能嵌套定义。 void表示无返回值,可以省略return,也可以单独的书写return,后面不加数据。 通用格式 1 2 3 4 public static 返回值类型 方法名(参数) { 方法体; return 数据 ; }
定义方法时,要做到两个明确明确返回值类型:主要是明确方法操作完毕之后是否有数据返回,如果没有,写void;如果有,写对应的数据类型 明确参数:主要是明确参数的类型和数量 调用方法时的注意:void类型的方法,直接调用即可 非void类型的方法,推荐用变量接收调用 方法重载 方法重载指同一个类中定义的多个方法之间的关系,满足下列条件的多个方法相互构成重载多个方法在同一个类 中 多个方法具有相同的方法名 多个方法的参数不相同,类型不同或者数量不同 注意:重载仅对应方法的定义,与方法的调用无关,调用方式参照标准格式 重载仅针对同一个类中方法的名称与参数进行识别,与返回值无关,换句话说不能通过返回值来判定两个方法是否相互构成重载 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 import java.util.Scanner;public class compare { public static void main (String[] args) { Scanner sc = new Scanner(System.in); System.out.println("请输入两个数\n" ); int a = sc.nextInt(); int b = sc.nextInt(); System.out.println(compare_byte((byte ) a, (byte ) b)); System.out.println(compare_short((short ) a, (short ) b)); System.out.println(compare_int(a, b)); System.out.println(compare_long((long ) a, (long ) b)); } public static boolean compare_byte (byte a, byte b) { return a == b; } public static boolean compare_short (short a, short b) { return a == b; } public static boolean compare_int (int a, int b) { return a == b; } public static boolean compare_long (long a, long b) { return a == b; } }
方法参数传递 基本类型 对于基本数据类型的参数,形式参数的改变,不影响实际参数的值
引用类型 对于引用类型的参数,形式参数的改变,影响实际参数的值
应用 数组遍历 1 2 3 System.out.println(“内容”); 输出内容并换行 System.out.print(“内容”); 输出内容不换行 System.out.println(); 起到换行的作用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public class MethodTest01 { public static void main (String[] args) { int [] arr = {11 , 22 , 33 , 44 , 55 }; printArray(arr); } public static void printArray (int [] arr) { System.out.print("[" ); for (int x=0 ; x<arr.length; x++) { if (x == arr.length-1 ) { System.out.print(arr[x]); } else { System.out.print(arr[x]+", " ); } } System.out.println("]" ); } }
Debug模式 是供程序员使用的程序调试工具,它可以用于查看程序的执行流程 ,也可以用于追踪程序执行过程来调试程序 。
操作流程 Debug调试,又称为断点调试,断点即为一个标记,告诉我们从哪里开始查看。
如何加断点 选择要设置断点的代码行,在行号的区域后面单击鼠标左键即可。
如何运行加断点的程序 在代码区域右键Debug执行。
看哪里 点哪里 点Step Into (F7)这个箭头,也可以直接按F7 —程序继续执行 点stop结束 删除断点 选择要删除的断点,单击鼠标左键即可。如果是多个断点,可以每一个再点击一次。也可以一次性全部删除。
注意 如果有键盘录入数据,记得前往Console录入数据 如果有方法调用,Debugger窗口则会显示方法
应用 Switch 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 import java.util.Scanner;public class fit_switch { public static void main (String[] args) { Scanner sc = new Scanner(System.in); System.out.println("请输入星期数:" ); int number = sc.nextInt(); switch (number) { case 1 : System.out.println("跑步" ); break ; case 2 : System.out.println("游泳" ); break ; case 3 : System.out.println("慢走" ); break ; case 4 : System.out.println("动感单车" ); break ; case 5 : System.out.println("拳击" ); break ; case 6 : System.out.println("爬山" ); break ; case 7 : System.out.println("大吃一顿" ); break ; default : System.out.println("你输入的星期数有误!" ); } } }
不死神兔 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 public class Test04 { public static void main (String[] args) { int [] arr = new int [20 ]; arr[0 ] = 1 ; arr[1 ] = 1 ; for (int x=2 ; x<arr.length; x++) { arr[x] = arr[x-2 ] + arr[x-1 ]; } System.out.println("第二十个月兔子的对数是:" + arr[19 ]); } }
百钱百鸡 循环穷举 —解方程 我国古代数学家张丘建在《算经》一书中提出的数学问题:鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一。 百钱买百鸡,问鸡翁、鸡母、鸡雏各几何?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class Test05 { public static void main (String[] args) { for (int x=0 ; x<=20 ; x++) { for (int y=0 ; y<=33 ; y++) { int z = 100 - x - y; if (z%3 ==0 && 5 *x+3 *y+z/3 ==100 ) { System.out.println(x+"," +y+"," +z); } } } } }
查找 已知一个数组 arr = {19, 28, 37, 46, 50}; 键盘录入一个数据,查找该数据在数组中的索引。并在控制台输出找到的索引值。如果没有查找到,则输出-1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 public class Test08 { public static void main (String[] args) { int [] arr = {19 , 28 , 37 , 46 , 50 }; Scanner sc = new Scanner(System.in); System.out.println("请输入要查找的数据:" ); int number = sc.nextInt(); int index = getIndex(arr, number); System.out.println("index: " + index); } public static int getIndex (int [] arr, int number) { int index = -1 ; for (int x=0 ; x<arr.length; x++) { if (arr[x] == number) { index = x; break ; } } return index; } }
反转 已知一个数组 arr = {19, 28, 37, 46, 50}; 用程序实现把数组中的元素值交换, 交换后的数组 arr = {50, 46, 37, 28,19}; 并在控制台输出交换后的数组元素。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 public class Test09 { public static void main (String[] args) { int [] arr = {19 , 28 , 37 , 46 , 50 }; reverse(arr); printArray(arr); } public static void reverse (int [] arr) { for (int start = 0 , end = arr.length - 1 ; start <= end; start++, end--) { int temp = arr[start]; arr[start] = arr[end]; arr[end] = temp; } } public static void printArray (int [] arr) { System.out.print("[" ); for (int x = 0 ; x < arr.length; x++) { if (x == arr.length - 1 ) { System.out.print(arr[x]); } else { System.out.print(arr[x] + ", " ); } } System.out.println("]" ); } }
类和对象 客观存在的事物皆为对象 ,所以我们也常常说万物皆对象。 面向对象(Object-Oriented):理解面对的对象。
OO分析:在问题域建立对象模型 OO设计:对解决方案建模 OO编程:使用面向对象程序设计语言进行编码实现 类类的理解类是对现实生活中一类具有共同属性和行为的事物的抽象 类是对象的数据类型 ,类是具有相同属性和行为的一组对象的集合 简单理解:类就是对现实事物的一种描述 类的组成属性:指事物的特征,例如:手机事物(品牌,价格,尺寸) 行为:指事物能执行的操作,例如:手机事物(打电话,发短信) 对象在认知心理学中,对象是指可触摸、可见或思维可理解的东西。 软件工程中的定义:对象是一个具有状态、行为和标识的实体。相似对象的结构和行为在它们的共有的类中定义。 类和对象的关系类:类是对现实生活中一类具有共同属性和行为的事物的抽象 对象:是能够看得到摸的着的真实存在的实体 简单理解:类是对事物的一种描述,对象则为具体存在的事物 (类是对象的抽象,对象是类的实体) 类 类是JAVA程序的基本组成单位。
类的组成是由属性和行为两部分组成: 属性:在类中通过成员变量来体现(类中方法外的变量) 行为:在类中通过成员方法来体现(和前面的方法相比去掉static关键字即可)
定义 1 2 3 4 5 6 7 8 9 10 11 12 ①定义类 ②编写类的成员变量 ③编写类的成员方法 public class 类名 { 变量1 的数据类型 变量1 ; 变量2 的数据类型 变量2 ; … 方法1 ; 方法2 ; }
一个包里面有很多个类,其中有一个主类,包含main方法,并可以通过包里面的其他类来定义对象
对象 1 2 3 4 5 创建对象: 类名 对象名 = new 类名(); 调用成员的格式: 对象名.成员变量 对象名.成员方法();
对象内存图 单个对象 成员对象 成员方法 多个对象 成员变量 成员方法 多个对象在堆内存中,都有不同的内存划分,成员变量存储在各自的内存区域中,成员方法多个对象共用的一份
多个对象相同内存 当多个对象的引用指向同一个内存空间(变量所记录的地址值是一样的) 只要有任何一个对象修改了内存中的数据,随后,无论使用哪一个对象进行数据获取,都是修改后的数据。
成员表量和局部变量 区别 成员变量 局部变量 类中位置不同 类中方法外 方法内部或方法声明上 内存中位置不同 堆内存 栈内存 生命周期不同 随着对象的存在而存在,随着对象的消失而消失 随着方法的调用而 存在,随着方法的调用完毕而消失 初始化值不同 有默认初始化值 没有默认初始化值,必须先定义,赋值才能使用
封装 private关键字 private 是一个权限修饰符,可以用来修饰成员(成员变量,成员方法) 作用是保护成员不被其他类使用,被 private 修饰的成员只能在本类中才能访问
被 private 修饰的成员,只能在本类进行访问,针对 private 修饰的成员变量,如果需要被其他类使用,提供相应的操作提供“get变量名()”方法,用于获取成员变量的值,方法用 public 修饰 提供“set变量名(参数)”方法,用于设置成员变量的值,方法用 public 修饰 this关键字 this修饰的变量用于指代成员变量,其主要作用是(区分局部变量和成员变量的重名问题)
内存原理 this 代表当前调用方法的引用,哪个对象调用的方法,this 就代表哪一个对象
封装 概述 封装是面向对象三大特征之一(封装,继承,多态); 是面向对象编程语言对客观世界的模拟,客观世界里成员变量都是隐藏在对象内部的,外界是无法直接操作的。
原则 将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏。 信息的操作和访问成员变量private,提供对应的getXxx()/setXxx()方法。
好处 通过方法来控制成员变量的操作,提高了代码的安全性 。 把代码用方法进行封装,提高了代码的复用性 。
构造方法 概述 1 2 3 4 5 6 7 8 9 10 11 public class 类名 { 修饰符 类名( 参数 ) { } }
注意事项 创建
当类中无构造方法时,系统将会默认给出一个无参构造方法,如果定义了构造方法,系统将不再提供默认的构造方法。 重载
如果自定义了带参构造方法,还要使用无参数构造方法,就必须再写一个无参数构造方法。 推荐
标准类制作 成员变量 构造方法 成员方法提供每一个成员变量对应的getXxx()/setXxx()方法 提供一个显示对象信息的show() 创建对象并为其成员变量赋值的两种方式无参构造方法创建对象后使用**setXxx()**赋值 使用带参构造方法直接创建带有属性值的对象 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 package com.Study_01.student;public class Student { private String name; private int age; public Student () { } public Student (String name, int age) { this .name = name; this .age = age; } public void setName (String name) { this .name = name; } public String getName () { return name; } public void setAge (int age) { this .age = age; } public int getAge () { return age; } public void show () { System.out.println(name + "," + age); } }
1 2 3 4 5 6 7 8 9 10 11 12 package com.Study_01.student;public class StudentDemo { public static void main (String[] args) { Student stu1 = new Student(); stu1.setName("李四" ); stu1.setAge(17 ); stu1.show(); Student stu2 = new Student("张三" ,18 ); stu2.show(); } }