do-while循环
在这里插入代码片
do - while 循环语句的格式: ( 开发中: 使用不多, 在java原码中)
格式:
初始化语句;
do {
循环体语句;
步长语句( 控制体语句) ;
} while ( 条件表达式) ;
执行流程:
1 ) 初始化语句赋值
2 ) 直接执行循环体语句-- -- > 步长语句-- - > 条件表达式
特点: 循环体至少执行一次 ( 它和while , for 的区别)
for循环的嵌套
for 循环的嵌套格式:
for ( 初始化语句; 条件表达式; 步长语句) {
for ( 初始化语句; 条件表达式; 步长语句) {
}
}
经典案例:
( 1 ) 控制台输出: 四行五列的* 形
for ( int x = 0 ; x < 4 ; x ++ ) {
for ( int y = 0 ; y < 5 ; y++ ) {
System. out. print ( "*" ) ;
}
System. out. println ( ) ;
}
( 2 ) 打印* 形
列数随着行数在变化
*
* *
* * *
* * * *
* * * * *
for ( int x = 0 ; x < 5 ; x ++ ) {
for ( int y = 0 ; y <= x ; y ++ ) {
System. out. print ( "*" ) ;
}
System. out. println ( ) ;
}
( 3 ) 99 乘法表
for ( int x = 1 ; x <= 9 ; x ++ ) {
for ( int y = 1 ; y<= x ; y ++ ) {
System. out. print ( y+ "*" + x + "=" + ( y* x) + "\t" ) ;
}
System. out. println ( ) ;
}
跳转控制语句
跳转控制语句:
break : 中断, 结束
continue : 结束当前循环, 立即进入下一次循环
return : 结束方法方法去使用的! ( 结合方法)
break : 中断, 结束的意思
不能单独使用, 没有意义!
在switch 中以及循环中使用!
循环中使用:
1 ) 可以在单层循环中使用
2 ) 早期的使用: 用在for 循环嵌套中使用( 外层循环, 内层循环)
标签语句
给外层循环/ 内层循环中起一个名字
格式: 标签名称: for ( 初始化语句; 条件表达式; 步长语句) { . . . }
标签名称: for ( ) { }
循环嵌套: 应用场景:
后期使用:
增强for 循环: 遍历集合
方法
什么是方法:
将一个独立的代码块{ } 抽取出来并为当前这个起名字! ( 作用: 提高代码的复用性)
方法的概念:
使用{ } 将代码包裹起来, 并给这个代码起一个名字: 方法名
-- -- > 以后直接使用方法名调用. { } 代码块
方法的定义:
( 1 ) 有返回值类型的方法的定义
固定格式:
public static 返回值类型 方法名( 形式参数类型1 参数名称1 , 形式参数类型2 参数名称2. . . ) {
业务需求. . .
return 结果;
}
格式的详细介绍:
权限修饰符: public ( 公共的, 访问权限足够大) static ( 静态)
返回值类型: 数据类型( 目前基本数据类型: 四类八种: )
举例: 求两个数据之后 结果: int 类型
方法名: 遵循标识符的规则( 见名知意)
单个单词: 全部小写
多个单独: 第一个单词小写, 从第二个单词开始, 每个单词首字母大写, 其余小写
小驼峰命名法!
形式参数类型: 数据类型( 目前基本数据类型: 四类八种: )
参数名称: 变量名称
return : 这个方法调用完毕了, 带回具体的结果!
有返回值类型的方法调用:
1 ) 单独调用( 没有意义)
2 ) 输出调用: 不推荐
3 ) 赋值调用: 推荐
( 2 ) 无返回值类型的方法的定义
Java的语法:
方法本身的定义: 需要返回值类型, 但是如果需求本身就没有具体返回结果, 如何定义方法呢?
语法要求: 如果没有具体返回值结果, 使用void 来代替 返回值类型( 位置)
注意: Java中不存在void 类型( 替代词)
没有具体返回值类型的方法的定义格式:
public static void 方法名( 形式参数类型1 变量名1 , 形式参数类型2 变量名2. . . ) {
直接输出语句或者其他业务操作;
}
没有具体返回值类型的方法调用
单独调用
赋值调用
输出调用
定义有具体返回值类型的方法的定义的注意事项!
1 ) 方法和方法平级关系, 不能嵌套使用!
特殊: 方法递归( IO流后面讲) : 方法调用方法本身的一种现象!
2 ) 定义方法注意两个明确
明确返回值类型
明确参数类型以及参数个数
3 ) 定义方法的时候:
参数类型必须携带的!
public static int and ( x, y) { } 错误的:
因为Java是一种强类型语言: 语法非常严谨的, 以及格式是有要求的!
4 ) 定义方法的时候, ( ) 后面不要出现; ( 目前来说没意义的方法! )
5 ) 调用方法的时候, 实际参数不需要携带数据类型
技术: 方法重载 ( overLoad)
方法名相同, 参数列表不同, 与返回值无关!
参数列表不同:
1 ) 数据类型一样的, 参数个数不同
2 ) 参数个数一样, 类型不同!
参数个数不一样, 参数类型不同
数组
步骤:
(1 )声明数组:声明数组名称和元素的数据类型
(2 )创建数组:为数组元素分配存储空间
(3 )数组的初始化:维数组元素赋值
数组的定义
1. 定义
• 数组是存储同一数据类型多个元素的集合。也可以看成是一个容器
• 数据既可以存储基本数据类型,也可以存储引用数据类型
2. 定义格式
• 格式1 :数据类型[ ] 数组名;
• 格式2 :数据类型 数组名[ ] ;
数组的初始化
为数组开辟内存空间,并为每个数组元素赋值
1. 静态初始化
初始化时由程序员显式指定每个数组元素的初始值,由系统决定数组长度
(1 )类型[ ] 数组名= new 类型[ ] { 元素,元素…} ;
(2 )类型[ ] 数组名= { 元素,元素,元素,…. } ;
举例:
String[ ] computers = { "Dell" , "Lenovo" , "Apple" , "Acer" } ;
String[ ] names = new String [ ] { "Dell" , "Lenovo" , "apple" , "Acer" } ;
2. 动态初始化
初始化时由程序员显示的指定数组的长度,由系统为数据每个元素分配初始值。
String[ ] cars = new String [ 4 ] ;
Java中内存分配
Java 程序在运行时,需要在内存中的分配空间。为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。
(1 )栈:存储局部变量,被调用方法参数
优点:存储速度比堆快,仅次于寄存器,栈数据可以共享。
缺点:数据的大小和生存期必需确定,缺乏灵活性。
(2 )堆:存放由new 创建的对象和数组
优点:可动态分配存储空间大小,Java垃圾回收器会自动收走不使用的数据
缺点:由于动态分配内存,存取速度较慢
(3 )方法区方法区中存放了每个Class的结构信息,
(4 )本地方法区(和系统有关)
(5 )寄存器(供CPU使用)
数组作为方法参数和返回值
(1 )对于基本数据类型的参数,是将实际参数值的一个拷贝传递给方法,方法调用结束后,对原来的值没有影响。
(2 )当参数是引用类型时,实际传递的是引用值,因此在方法的内部有可能改变原来的对象。
Java中使用增强的for 循环
格式:
for ( 循环变量类型循环变量名称: 要被遍历的对象) {
循环体
}
多维数组
二维数组:就是元素为一维数组的一个数组。
格式1 :
数据类型[ ] [ ] 数组名 = new 数据类型[ m] [ n] ;
m: 表示这个二维数组有多少个一维数组。
n: 表示每一个一维数组的元素有多少个。
格式2 :
数据类型[ ] [ ] 数组名 = new 数据类型[ m] [ ] ;
m: 表示这个二维数组有多少个一维数组。
列数没有给出,可以动态的给。这一次是一个变化的列数。
格式3 :
基本格式:
数据类型[ ] [ ] 数组名 = new 数据类型[ ] [ ] { { 元素1 , 元素2. . . } , { 元素1 , 元素2. . . } , { 元素1 , 元素2. . . } } ;
简化版格式:
数据类型[ ] [ ] 数组名 = { { 元素1 , 元素2. . . } , { 元素1 , 元素2. . . } , { 元素1 , 元素2. . . } } ;
说明:int [ ] arr = new int [ 3 ] ;
左边:
int : 说明数组中的元素的数据类型是int 类型
[ ] : 说明这是一个数组
arr: 是数组的名称
右边:
new : 为数组分配内存空间。
int : 说明数组中的元素的数据类型是int 类型
[ ] : 说明这是一个数组
数组长度,其实也就是数组中元素的个数( length)
经典案例:
( 1 ) 数组的遍历
输出格式为:
{ 元素1 , 元素2 , 元素3 , . . . . }
class ArrayTest {
public static void main ( String[ ] args) {
int [ ] arr = { 13 , 87 , 65 , 24 , 57 } ;
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. println ( arr[ x] + "}" ) ;
} else {
System. out. print ( arr[ x] + ", " ) ;
}
}
}
}
( 2 ) 最值问题
最大值/ 最小值
int [ ] arr = { 13 , 87 , 65 , 24 , 57 } ;
最值问题
分析: 假设思想
1 ) 将数组中第一个元素arr[ 0 ] 看为最大值
2 ) 从角标1 开始遍历其他元素
分别将当前遍历的元素依次和最大值进行比较
如果当前元素大于最大值
将当前元素内容赋值max变量
class ArrayData {
public static void main ( String[ ] args) {
int [ ] arr = { 13 , 87 , 65 , 24 , 57 } ;
int max = getMax ( arr) ;
System. out. println ( "数组中的最大值是:" + max) ;
int min = getMin ( arr) ;
System. out. println ( "数组中的最小值是:" + min) ;
}
public static int getMin ( int [ ] arr) {
int min = arr[ 0 ] ;
for ( int x = 1 ; x < arr. length ; x ++ ) {
if ( arr[ x] < min) {
min = arr[ x] ;
}
}
return min ;
}
public static int getMax ( int [ ] arr) {
int max = arr[ 0 ] ;
for ( int x = 1 ; x < arr. length ; x ++ ) {
if ( arr[ x] > max) {
max = arr[ x] ;
}
}
return max ;
}
}
( 3 ) 数组的元素逆序
int [ ] arr = { 13 , 87 , 65 , 24 , 57 } ;
中心思想:
将13 arr[ 0 ] -- 57 arr[ arr. length- 1 ] 互换
将87 arr[ 1 ] -- - 24 arr[ arr. length- 1 - 1 ] 互换. . . .
. . .
保证 数组的长度/ 2
class ArrayTest3 {
public static void main ( String[ ] args) {
int [ ] arr = { 13 , 87 , 65 , 24 , 57 } ;
System. out. println ( "数组逆序前: " ) ;
printArray ( arr) ;
System. out. println ( "----------------" ) ;
System. out. println ( "数组逆序后: " ) ;
reverse ( arr) ;
reverse2 ( arr) ;
printArray ( arr) ;
}
public static void reverse ( int [ ] arr) {
for ( int x = 0 ; x < arr. length/ 2 ; x ++ ) {
int temp = arr[ x] ;
arr[ x] = arr[ arr. length- 1 - x] ;
arr[ arr. length- 1 - x] = temp ;
}
}
public static void reverse2 ( 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. println ( arr[ x] + "]" ) ;
} else {
System. out. print ( arr[ x] + ", " ) ;
}
}
}
}
( 4 ) 冒泡排序
两两比较, 将较大的值往后放; 第一次比较完毕, 最大值就出现在最大索引处!
依次这样比较:
规律:
第一次: 有0 个不比
第二次: 有1 个不比
. . .
. . .
比较的次数: 数组长度- 1 次
class ArrayTest {
public static void main ( String[ ] args) {
int [ ] arr = { 24 , 69 , 87 , 57 , 13 } ;
System. out. println ( "排序前: " ) ;
printArray ( arr) ;
System. out. println ( "排序后:" ) ;
bubboleSort ( arr) ;
printArray ( arr) ;
}
public static void bubboleSort ( int [ ] arr) {
for ( int x = 0 ; x < arr. length- 1 ; x ++ ) {
for ( int y = 0 ; y < arr. length- 1 - x ; y++ ) {
if ( arr[ y] > arr[ y+ 1 ] ) {
int temp = arr[ y] ;
arr[ y] = arr[ y+ 1 ] ;
arr[ y+ 1 ] = 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. println ( arr[ x] + "]" ) ;
} else {
System. out. print ( arr[ x] + ", " ) ;
}
}
}
}
( 5 ) 二维数组的遍历
静态初始化:
int [ ] [ ] arr = { { 1 , 2 , 3 } , { 4 , 5 , 6 } , { 7 , 8 , 9 } } ;
输出结果:
{ { 1 , 2 , 3 } , { 4 , 5 , 6 } , { 7 , 8 , 9 } }
class Array2Test2 {
public static void main ( String[ ] args) {
int [ ] [ ] arr = { { 1 , 2 , 3 } , { 4 , 5 , 6 } , { 7 , 8 , 9 } } ;
printArray2 ( arr) ;
}
public static void printArray2 ( int [ ] [ ] arr) {
System. out. print ( "{" ) ;
for ( int x = 0 ; x < arr. length ; x ++ ) {
System. out. print ( "{" ) ;
for ( int y = 0 ; y < arr[ x] . length ; y ++ ) {
if ( x == arr. length- 1 && y == arr. length- 1 ) {
System. out. print ( arr[ x] [ y] + "}" ) ;
} else if ( y== arr[ x] . length- 1 ) {
System. out. print ( arr[ x] [ y] + "}" + "," ) ;
} else {
System. out. print ( arr[ x] [ y] + "," ) ;
}
}
}
System. out. print ( "}" ) ;
}
}
( 6 ) 二维数组的应用: 杨辉三角形
输出:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
分析:
1 ) 行数和列数: 都是6 -- -- - > 数据可以采用键盘录入!
二维数组的定义格式:
格式1 : int [ ] [ ] arr = new int [ num] [ num] ;
2 ) 任何一行的第一列和最后一列都是1
3 ) 从第三行开始, 中间的数据的值等于上一行的前一列+ 上一行的本列之和
要符合99 乘法表的格式!
import java. util. Scanner ;
class Array2Test {
public static void main ( String[ ] args) {
Scanner sc = new Scanner ( System. in) ;
System. out. println ( "请您输入一个数据:" ) ;
int n = sc. nextInt ( ) ;
int [ ] [ ] arr = new int [ n] [ n] ;
for ( int x = 0 ; x < arr. length ; x ++ ) {
arr[ x] [ 0 ] = 1 ;
arr[ x] [ x] = 1 ;
}
for ( int x = 2 ; x < arr. length ; x ++ ) {
for ( int y = 1 ; y <= x - 1 ; y ++ ) {
arr[ x] [ y] = arr[ x- 1 ] [ y- 1 ] + arr[ x- 1 ] [ y] ;
}
}
for ( int x = 0 ; x < arr. length ; x ++ ) {
for ( int y = 0 ; y <= x ; y ++ ) {
System. out. print ( arr[ x] [ y] + "\t" ) ;
}
System. out. println ( ) ;
}
}
}
基本类型作为形式参数进行传递的特点:
形式参数的改变对实际参数没有影响!
如果形式参数是一个引用数据类型: 数组
形式参数的改变对实际参数有影响!
String类型是一种特殊的引用类型:
它作为形式参数, 形参的改变对实际参数没有影响!
跟基本类型作为形式参数是一样!
面向对象(引入)
1. 面向对象是一种符合人类思维习惯的编程思想。现实生活中存在各种形态不同的事物,这些事物之间存在着各种各样的联系。在程序中使用对象来映射现实中的事物,使用对象的关系来描述事物之间的联系,这种思想就是面向对象。
2. 提到面向对象,自然会想到面向过程,面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一一实现,使用的时候依次调用就可以了。面向对象则是把构成问题的事务按照一定规则划分为多个独立的对象,然后通过调用对象的方法来解决问题。当然,一个应用程序会包含多个对象,通过多个对象的相互配合来实现应用程序的功能,这样当应用程序功能发生变动时,只需要修改个别的对象就可以了,从而使代码更容易得到维护。面向对象的特点主要可以概括为封装性、继承性和多态性。
1 、封装性
封装是面向对象的核心思想,将对象的属性和行为封装起来,不需要让外界知道具体实现细节,这就是封装思想。例如,用户使用电脑,只需要使用手指敲键盘就可以了,无需知道电脑内部是如何工作的,即使用户可能碰巧知道电脑的工作原理,但在使用时,并不完全依赖电脑工作原理这些细节。
2 、继承性
继承性主要描述的是类与类之间的关系,通过继承,可以在无需重新编写原有类的情况下,对原有类的功能进行扩展。例如,有一个汽车的类,该类中描述了汽车的普通特性和功能,而轿车的类中不仅应该包含汽车的特性和功能,还应该增加轿车特有的功能,这时,可以让轿车类继承汽车类,在轿车类中单独添加轿车特性的方法就可以了。继承不仅增强了代码的复用性、提高开发效率,还为程序的维护补充提供了便利。
3 、多态性
多态性指的是在程序中允许出现重名现象,它指在一个类中定义的属性和方法被其它类继承后,它们可以具有不同的数据类型或表现出不同的行为,这使得同一个属性和方法在不同的类中具有不同的语义。例如,当听到“Cut” 这个单词时,理发师的行为是剪发,演员的行为表现是停止表演,不同的对象,所表现的行为是不一样的。
分类:静态多态性和动态多态性
3. 面向对象的编程思想,力图让程序中对事物的描述与该事物在现实中的形态保持一致。为了做到这一点,面向对象的思想中提出了两个概念,即类和对象。其中,类是对某一类事物的抽象描述,而对象用于表示现实中该类事物的个体。接下来通过一个图例来抽象描述类与对象的关系,如下图所示。
下图可以将玩具模型看作是一个类,将一个 玩具看作对象,从玩具模型和玩具之间的关系便可以看出类与对象之间的关系。类用于描述多个对象的共同特征,它是对象的模板。对象用于描述现实中的个体,它是类的实 例。从图可以明显看出对象是根据类创建的,并且一个类可以对应多个对象。
1. 现实世界的事物
属性 人的身高,体重等
行为 人可以学习,吃饭等
2. Java中用class 描述事物也是如此
成员变量 就是事物的属性
成员方法 就是事物的行为
3. 定义类其实就是定义类的成员(成员变量和成员方法)
在Java中,定义在类中的变量被称为成员变量,定义在方法中的变量被称为局部变量。
4. 成员变量和局部变量的区别:
1 ) 在类中的位置不同
成员变量 类中方法外
局部变量 方法内或者方法声明上
2 ) 在内存中的位置不同
成员变量 堆内存
局部变量 栈内存
3 ) 生命周期不同
成员变量 随着对象的存在而存在,随着对象的消失而消失
局部变量 随着方法的调用而存在,随着方法的调用完毕而消失
4 ) 初始化值不同
成员变量 有默认的初始化值
局部变量 没有默认的初始化值,必须先定义,赋值,才能使用。
5. 对象的创建与使用
应用程序想要完成具体的功能,仅有类是远远不够的,还需要根据类创建实例对象。在Java程序中可以使用new 关键字来创建对象,具体格式如下:
类名 对象名称 = new 类名( ) ;
6. 创建对象后,可通过对象的引用来访问对象所有的成员。
对象引用. 对象成员
7. 类的初始化过程
例如: Student s = new Student ( ) ;
做了哪些事情
1 ) 加载Student. class 文件进内存
2 ) 执行main方法,在栈中开辟main方法空间,然后在main方法的栈区分配了一个变量p
3 ) 在堆内存为学生对象开辟空间,分配内存首地址值
4 ) 对学生对象的成员变量进行默认初始化
5 ) 对学生对象的成员变量进行显式初始化
6 ) 通过构造方法对学生对象的成员变量赋值
7 ) 学生对象初始化完毕,把对象地址赋给变量s
8. 在实例化对象时 ,Java虚拟机会自动为成员变量进行初始化,针对不同类型的成员变量,Java虚拟机会赋予不同的初始值,如下表所示。
9. 当对象被实例化后,在程序中可以通过对象的引用变量来访问该对象的成员。需要注意的是,当没有任何变量引用这个对象时,它将成为垃圾对象,不能再被使用。