第一部分 语法基础篇
第一章 概述
1.1计算机组成部分
计算机的组成主要分成两大类:硬件,软件
硬件是可以看到的一些物理部分,都是一些电子元件
软件是看不到的部分,它是一些列的指令,这些指令主要用于控制硬件来玩成一些特殊的工作
常见的硬件:
.CPU;Cent Processing Unit是中央处理器 主要指控制和数值计算功能(日常工作任务)
.内存;临时性存储设备RAM,当内存不通电的时候,这数据也就消失了
. 显卡CPU;Grqphic processing Unit图形图像处理单元 主要用于计算图形数据(图形图像任务)
存储设备;永久性存储设备ROM任何数据都是二进制的形式存储的
机械硬盘
固态硬盘
u盘
光盘
移动硬盘
输入输出设备
键盘;输入字符的数据
鼠标;输入定位数据
显示器;输出图形图像数据
扬声器;输出声音数据
麦克风;声音输出设备
打印机;输出图形图案文本数据
扫描仪;输入图形图像文本数据
网络设备
输入;从互联网上下载数据
输出’从本地上传到互联网
1.2人机交互方式
我们如何与计算机打交道的
图形化界面操作方式
优点;操作简单,容易上手操作,表现直观
缺点;步骤复杂,占用空间大
命令操作方式cmd(Command win+输入cmd回车)窗口;
缺点;操作复杂,命令较多,不容易上手
优点;步骤简单,占用空间小,适合远程操作
常用dos命令
c:进入c盘根部目录
D:进入D盘根部目录
cd/xx进入xxx目录
dir查看当前目录下有什么文件和目录
cd/计入到当前所在盘符的根目录
cd…返回到上一级目录
cls清屏
exit退出cmd窗口
1.3 计算机语言
计算机本身就是有一系列物理硬件组成的,它们之间的沟通方式就是电信号,高低电压-二进制数据,所以和计算机之间打交道,就得通过二进制来做,早期的编程语言/命令都是以二进制形式存在
机器语言
根据平台的不同其所表现的形式也不同,为了让计算机能够懂得人类的目的,人类必须以二进制的形式向计算机输入数据。计算机能懂,人不太懂,对初学者十分不友好的。比如要计算两个数字的加法
汇编语言
通过一些单词也叫助记符,将一些常用的操作用单词表示,在程序中慢慢出现了人类的语言。比如计算2+3的结果,在汇编语言里是一下结果。这种代码计算机读不懂,还得将这些助记符包括数据转换成对应的二进制提交给计算机进行计算。转换的工具,称之为汇编器。汇编语言它的计算方式,还是依赖于计算机的计算方式的。想学好汇编语言,还得事先了解计算机的工作原理。
高级编程语言
从20世纪50年代产生,第一个众所周知的高级编程语言:C语言->C++语言->Java语言->C#-Python
高级编程语言完全由单词,符号和数字组成,并且书写流程也是符号人类流程。比如计算2+3如下代码所示,更容易让人类去理解。同样计算机不能够读懂这段代码,还得将代码进行转换二进制提交给计算机。
转换的形式:编译,解释
静态编译语言:C C++ Java
静态:在定义变量的时候有明确的数据类型的区分
编译:将源代码全部进行编译 生成一个可执行的二进制文件 计算机去执行这个二进制文件来运行程序
动态解释语言:Python JS
动态:在定义变量的时候没有明确的数据类型的区分
解释:将源代码从头到尾 读取一行 编译一行 运行一行(同声传译)
1.4 软件与软件开发
软件的定义
软件 是 指一系列按照特定顺序组织的 计算机数据与指令 的 集合
100101001010100101010101 add 2,3 reslut int a = 2 + 3;
举例:向西走50米 然后 左转向前走20米
输入三个点的坐标通过三边来计算一个三角形的面积?
说明:再用编程去解决一个问题的时候,先去获取该问题所需要的数据,然后再根据数据讨论计算的具体流程,最后再用编程语言去实现这个计算的流程
软件的分类只分两类:
系统软件:也称之为是操作系统,主要是用来控制和管理底层硬件的一套指令,操作系统为用户提供最基本的计算机功能。
应用软件:基于系统软件之上的,为用户带了特定领域服务的软件
软件开发
软件开发的定义就是去编写上述软件,软件开发的流程是什么?
- 需求分析
- 编码实现
- 测试编码
- 上线运维
- 更新迭代
- 下线
1.5 Java语言介绍
Java语言的前身Oak(橡树),1994年詹姆斯高斯林和他的团队开发出来的嵌入式编程语言互联网的发展,紧随潮流编程互联网应用程序开发语言(面向对象),一直到2010年Sun公司被收购,Java就属于Oralce的子产品。
Oracle公司主要业务:数据库 Oralce数据库 随后也把民间产品MySQL也收购了Linux服务器操作系统Solaris(redhat Ubuntu 深度 SUSE)编程语言Java
Microsox公司主要业务:SQL Server Windows/Windows Server C++/C#
Java技术架构
JavaSE Java Standard Edition Java标准版:桌面型应用程序JavaEE Java Enterprise Edition Java企业版:服务器应用程序JavaME Java Micro Edition Java微型版:嵌入式应用程序
Java最大的特点——跨平台跨平台的意思就是说,一个软件可以在多个平台上运行,而不用更改软件的内容。是因为JVM的功劳:
JVM(Java Virtual Machine)Java虚拟机。
Java源代码文件后缀名为xxx.java 所编译出来的二进制文件后缀名为xxx.class
JVM主要负责将java语言的字节码文件转换为本地操作系统指令的一个工具软件。所以,最终是字节码文件在跨平台!
1.6 Java开发环境搭建 JRE与JDK
JRE(Java Runtime Environment)Java运行环境:如果我们的计算机仅仅想运行Java程序的话,装这个软件即可。JRE = JVM + 核心类库。
JDK(Java Development Kit)Java开发工具包:如果我们的计算机想要去开发一个Java程序的话,
装这个软件即可。JDK = 开发工具 + JRE。 JDK的下载与安装
- 先登录注册Oracle 2. 去Oralce官网下载JDK,最新JDK15,我们目前用JDK8 https://www.oracle.com 3. 点击Products 4. 点击SoxWare下的Java 5. 右上角DownloadJava 6. 找到JavaSE8 点击JDK Download 7. 下拉 在下载列表中选择Windows X64 8. 双击打开jdk安装程序
- 点击下一步
- JDK不需要更改目录 直接下一步
- JRE不需要更改目录 直接下一步
- 安装完成 点击关闭即可
- 验证jdk是否安装成功
- win+r 打开cmd 输入 java -version
说明安装成功!
java version “1.8.0_77” Java™ SE Runtime Environment (build 1.8.0_77-b03) Java HotSpot™ 64-Bit Server VM (build 25.77-b03, mixed mode)
jdk安装目录介绍
bin目录:binary放的都是开发工具
javac.exe:java编译工具
用法: javac java.exe:java运行工具
用法: java [-options] class [args…] (执行类) 或 java [-options] -jar jarfile [args…] (执行 jar 文件) db目录:放的是支持数据库开发的一些工具包
include目录:放的是一些链接底层的一些C头文件代码
jre目录:jdk自带的运行环境
lib目录:library 存放的是一些第三方Java库 javafx-src.zip:javafx图形化界面开发的源码包
src.zip:Java本身的源代码包
配置path环境变量
- 复制jdk中bin目录的绝对地址 C:\Program Files\Java\jdk1.8.0_77\bin 2. 右键此电脑 点击属性
- 点击高级系统设置
- 点击环境变量
- 系统变量中选择Path 6. 右上角 新建 将地址复制进去即可
- 一路确定出去
- 重启cmd 再去尝试javavc java
关于classpath的配置暂且不说
1.7 运行Java程序 VSCode代码编辑器 https://code.visualstudio.com/汉化:左下角管理 Extension 搜索Chinese 选择Chinese中文简体汉化包 重启 重启即可主题:管理 颜色主题 自选编码:管理 设置 文本编辑器 文件 Encoding 选择gbk结尾字体:管理 设置 文本编辑器 字体 font size关联代码所在的文件夹:文件 打开文件夹 选择JavaDay01步骤一:新建Java源代码文件并写入类点击新建文件按钮,输入Java源代码文件名称和后缀名,例如Sampl在文件中写入如下代码:public class Sample01 { } public class Sample01 中的 Sample01 是类名,而且在Java源代码最多只能有一个public开头的类,并且该类的类名必须与文件名保持一步骤二:编译该源代码文件打开控制台窗口cmd,将目录切换到JavaDay01目录下C:\Users\HENG>cd Desktop C:\Users\HENG\Desktop>cd JavaDay01再输入 javac Sample01.java 对源代码文件进行编译C:\Users\HENG\Desktop\JavaDay01>javac Sample01.java如果没有任何输出,则表明编译成功,并生成同名的字节码文件 Sam步骤三:运行该字节码文件输入 java Sample01 即可C:\Users\HENG\Desktop\JavaDay01>java Sample01 错误: 在类 Sample01 中找不到 main 方法, 请将 main 方法定义为: public static void main(String[] args) 否则 JavaFX 应用程序类必须扩展javafx.application.Application此时发现运行工具提示错误,对于任何一个程序而言,程序的运行都入其中。public class Sample01 { public static void main(String[] args) { System.out.println(“Hello World!”); } }再重新编译和运行C:\Users\HENG\Desktop\JavaDay01>javac Sample01.java C:\Users\HENG\Desktop\JavaDay01>java Sample01 Hello World!C:\Users\HENG\Desktop\JavaDay01>javac Sample01.java Sample01.java:1: 错误: 类hehe是公共的, 应在名为 hehe.java 的文public class hehe { ^ 1 个错误注意!源代码文件名和类名必须一致!
1.8 常见错误
语法错误
指在编译的过程中出现的一些错误,这种错误的原因主要由那些因素产生呢?
单词评写
遗漏分号
使用中文符号的问题
大括号不匹配
遗漏关键字单词
运行错误
是指编译能够通过,但是在运行期间出现的问题
逻辑错误
代码的运行结果和自己认为的结果不一样!
遗漏括号
遗漏分号
遗漏引号
第2章 基本数据与运算
2.1 关键字
关键字是指被高级编程语言赋予特殊含义的一些单词,关键字一般都是由小写字母组成。好比是汉
语当中的一些专有名词:北京,天安门,兵马俑。不能乱用。
用于定义数据类型的关键字:byte short int long float double char boolean void class interface
用于定义数据类型值的关键字:true false null
用于定义流程控制语句的关键字:if else switch case default while do for break continue return
用于定义访问权限修饰符的关键字:public protected private
用于定义继承关系的关键字:extends implements
用于定义实例对象的关键字:new this super instanceof
用于定义函数类型的关键字:static final abstract synchronized
用于处理异常的关键字:try catch finally throw throws public class Demo01 { public static void main(String[] args) { System.out.println((9.5 * 4.5 - 2.5 * 3) / (45.5 - 3.5)); } }public class Demo04 { public static void main(String[] args) { System.out.println(14 / 1.6 / (45 * 60 + 30) * 3600 + “英里/小时”); } }public class Demo06 { public static void main(String[] args) { System.out.println(“x=” + (44.5 * 0.55 - 50.2 * 5.9) / (3.4 * 0.55 - 50.2 * 2.1)); System.out.println(“y=” + (3.4 * 5.9 - 44.5 * 2.1) / (3.4 * 0.55 - 50.2 * 2.1));} }
用于包的关键字:package import
其他的一些修饰关键字:native assert volatile transient
2.2 标识符
标识符指的是我们在程序中对变量、函数、类、接口、常量所定义的名称,也就是说这些名称是我
们自定义的。
标识符必须满足以下组成规则:
标识符可以由数字、字母、下划线 _ 、美元符 $ 组成
标识符不能以数字开头,当然下划线和美元符其实是可以开头的,但不推荐
标识符不能是关键字
标识符也不能是Java内置类的名称
标识符可以为任意长度,但必须是一个连续的词
标识符严格区分大小写
标识符是为那些抽象的数据进行的自定义起名,为了方便程序的阅读和理解,起名尽量要有
含义,不要通篇都是a b c d e f g…。在一些特殊的情况下(循环里 特殊数学符号),可以使用i j k m n 之类的。
标识符命名的规范:
大驼峰式:主要针对类名,接口名。所有单词的首字母大写
小驼峰是:主要针对于变量名,函数名。除了第一个单词之外,其他单词首字母大写
常量规范:所有单词字母大写,单词与单词之间用下划线分隔
包名规范:所有单词字母小写,单词与单词之间用句号 . 分隔
2.3 注释
注释是用于注解和说明程序的一些程序中的内置文本信息的,但这些内置文本不属于代码的范畴。
所以在对含有注释的源代码进行编译时,所生成的字节码中不含有注释。注释给人看的!
注释主要有三种:
单行注释 //注释内容 直到换行为止
多行注释 /* 注释内容 内部可以进行换行 /
文档注释 / 注释内容 内部可以进行换行 / :文档注释可以被编译器识别,并生成相应
的程序说明书。对某一个类进行文档生成时,该类必须是public型 myAge 变量名 getMax() 函数名 MyMoney 类名 接口名 MAX_VALUE 常量名 com.oupeng.java 包名 / 这是一个演示类 名字叫Sample @author HENG @version 1.0 /public class Sample { /* 这是一个主函数,是程序的入口 @param args 在运行主函数是 所传入的一些指令的 @return 该主函数没有返回值
额外的,注释除了有解释说明程序的功能之外,还可以用来调试程序。
多行注释中,不能再出现多行注释
今后,在写代码时,一定要先写注释,并且,注释最好详细一些
2.4 常量与进制
常量就是指在程序中直接出现的一些数据,也叫字面量
常量都有哪些:
整数常量
小数常量
字符常量:由一个字母、数字、符号被单引号( ‘’ )标识的数据
字符串常量:由若干个字母、数字、符号被双引号( “” )标识的数据
布尔类型常量
null常量
*/public static void main(String[] args) { } }C:\Users\HENG\Desktop\JavaDay02>javadoc Sample.java public class Sample { public static void main(String[] args) { //整数常量 System.out.println(10); //十进制整数 System.out.println(0b1001); //二进制整数 打印出来是十进制 System.out.println(0123); //八进制整数 System.out.println(0xAF3); //十六进制整数 //小数常量 System.out.println(3.14); System.out.println(5.234e3); System.out.println(1.2e-3); //字符常量 System.out.println(‘a’); //System.out.println(‘ab’); ERROR System.out.println(‘9’); //System.out.println(‘12’); ERROR System.out.println(‘我’); System.out.println(’ ‘); //System.out.println(’’); ERROR //System.out.println(’’’); ERROR System.out.println(’’’); //打印 ’ System.out.println(’\n’); //打印 换行 System.out.println(’\t’); //打印 缩进 //字符串常量 System.out.println(“abcd”); System.out.println(“a”); System.out.println(""); //字符串空串 vs null真空 System.out.println("""); //布尔常量 System.out.println(true);
十进制 二进制数
0 0 1 1 2 10 3 11 4 100 5 101 6 110 7 111 8 1000
二进制转十进制
规律就是:1 1 1 1 1 1 1 1 - 128 64 32 16 8 4 2 1 10010101 十进制是 128 + 16 + 4 + 1 = 149
十进制149 = 9 * 100 + 4 * 101 + 1 * 102
二进制1011 = 1 * 20 + 1 * 21 + 0 * 22 + 1 * 23 = 1 + 2 + 0 + 8 = 11
一个二进制位称之为是一个比特 bit;八个比特称之为一个字节 byte;字节是计算机当中的最小计
数单元。
1 byte = 8 bit 1 kb = 1024 byte 1 mk = 1024 kb 1 gb = 1024 mb 1 tb = 1024 gb
十进制转二进制
53 ÷ 2 = 26 ~ 1 26 ÷ 2 = 13 ~ 0 13 ÷ 2 = 6 ~ 1 6 ÷ 2 = 3 ~ 0 3 ÷ 2 = 1 ~ 1 1 ÷ 2 = 0 ~ 1
余数从下到上 110101 = 1 + 4 + 16 + 32 = 53
二进制转八进制
10010101 => 010-010-101 => 0225 = 5 * 80 + 2 * 81 + 2 * 82 =5 + 16 + 128 = 149
二进制转十六进制
System.out.println(false); } }
10010101 => 1001-0101 => 0x95 = 5 * 160 + 9 ^ 161 = 5 + 144 = 149
二进制转六进制
10010101 => 149 149 ÷ 6 = 24 ~ 5 24 ÷ 6 = 4 ~ 0 4 ÷ 6 = 0 ~ 4
所以六进制为405 => 5 * 60 + 0 * 61 + 4 * 62 = 5 + 0 + 144 = 149
负数的二进制
-29的二进制 将正数部分的二进制先取反 再加1 即为负数的二进制
00011101 =>取反 11100010 =>加1 11100011
2.5 变量
指的是变化的量
变量的本质就是在内存中程序所处的进程中的一个临时存储区域
该区域的存储值有限制的
该区域值的变化必须是同类型的或向下兼容的
该区域有其自身的物理内存地址-指针
该区域中 存储值的限制 和 数据的变化类型 由 数据类型 来决定
该区域中 其空间的分配 和 空间的物理内存地址 由计算机底层来决定
2.6 数据类型 在Java当中,数据类型主要分为两大类:
基本数据类型:在变量的空间中存储数据
整型
byte 1字节 2^8 256 -128~127 -2^7 ~ 2^7 - 1 short 2字节 2^16 65536 -32768~32767 -2^15 ~ 2^15 - 1 int 4字节
long 8字节
浮点型
float 4字节
double 8字节
字符型
char 2字节
布尔型
boolean 不确定
在常量中,整型常量默认int类型,小数常量默认是double类型
布尔类型,如果是单一变量的话,在JVM中true被认为是1 false被认为是0 所以是4字节存
如果是布尔类型数组的话,在JVM中true和false被认为是byte类型 1字节
引用数据类型:数据是在堆内存中存储,变量仅仅存放的是数据在堆内存中的地址
字符串
数组
对象
在Java中,但凡存储在堆内存中的数据,统称为对象
2.7 运算符
算术运算符
long l1 = 123123123123; ^ 1 个错误 */long l2 = 123123123123L; //long类型的常量 //long l3 = 123123123123123123123L; //error 爆了long的表 //float f = 3.14; //error /*Sample.java:85: 错误: 不兼容的类型: 从double转换到float可能会有损失
float f = 3.14; ^ 1 个错误 */
float f = 3.14f; double d1 = 3.14; double d2 = 10; double d3 = 3.14f; double d4 = f; double d5 = b1 + s1 + i2 + l2; //也会出现溢出的问题 //char类型而言 变量空间存的是ASCII编号 char c1 = ‘a’; //将字符a的编号存到c1里 char c2 = ‘A’; System.out.println(c1); System.out.println(c2); System.out.println(c1 + c2); char c3 = 97; char c4 = 65; System.out.println(c3); System.out.println(c4); System.out.println((char) 98); System.out.println((char)(c1 + 4)); System.out.println(‘0’ + 0); //'a’97 'A’65 '0’48 boolean bool1 = true; boolean bool2 = false; } }
算数运算
符
含义 备注
- 加法 1+2=3 如果加号左右有字符串 则加号为连接符
- 加法 3-2=1 * 乘法 3*2=6 / 除法 3/2=1 3.0/2=1.5 如果除号两边都是整数 结果为整数;有小数 结果为小
数 % 取余 9%5=4 注意一点,如果前或后为负数怎办?
a++
后置自身加一,使用原来的值
++a
前置自身加一,使用加之后的值
a–
后置a自身减一,使用原来的值
–a
前置自自身减一,使用减之后的值
赋值运算符
public class Sample { public static void main(String[] args) { /*a++ 1.先开辟临时存储区 将a的值赋值进去 2.a自身加一 3.临时存储区的值等待被调用 输出 赋值 参与运算 /int i = 0; i++; System.out.println(i++); //1 System.out.println(i); //2 int j = i++; System.out.println(i); //3 System.out.println(j); //2 i = i++; System.out.println(i); //3 i = i++; System.out.println(i); //3 int a = 1; System.out.println(a++ + ++a + a++ + a++ + ++a); // 1 3 3 4 6 } }
赋值运算符 含义
+= 加法赋值 a+=3 a=a+3 赋值运算符只能用在变量身上
-==/=%=
比较运算符
运算的结果为布尔类型
.> 大于
< 小于
.>= 大于等于
<= 小于等于
!= 不等于
逻辑运算符
& 单与
| 单或
^ 异或
! 非&& 双与
|| 双或
位运算符
& 位与
public class Sample { public static void main(String[] args) { int x = 0; int y = 0; System.out.println(x++ > 0 & y++ > 0); System.out.println(x); System.out.println(y); x = 0; y = 0; System.out.println(x++ > 0 && y++ > 0); System.out.println(x); System.out.println(y)
&& 如果左边为假 则右边不用执行
|| 如果左边为真 则右边不用执行
| 位或
^ 位异或
.>>右移
<< 左移
三目运算符
数据类型 变量名 = 布尔表达式?值1:值2;
int number = 10 % 2 == 0? 10 : 2;
补充:变量的交换问题:
int a = 3; int b = 7;
方法一:
方法二:
方法三:
2.8 常见错误
未声明变量,未初始化变量而使用变量
整型溢出问题
取整错误
一个是小数的问题,小数主要去的是近似值 想要得到一个0.5这个值的话 有可能会得到0.4999999
一个是整数的问题,1/3 = 0.3333 * 3 = 0.99999 数学上1
超出预期的除法问题
左右两边是整数,结果为整数,如果出现小数则结果为小数
额外冗余的输入对象
2.9 编程练习题
课后作业
Demo08
Demo10
Demo13
Demo14
Demo16
第3章 流程控制语句
3.1 if条件语句
单分支if语句
…CodeA
if (布尔表达式) {
语句组;
}…CodeB
双分支if-else语句
…CodeA
if (布尔表达式) { 语句组A
; } else {
语句组B;
}…CodeB
3.2 switch分支语句 与if分支语句一样,都是对条件的判断。switch一般用在条件较多的情况下,但是有一个重要的细节
及时,if语言可以对区间值或固定值进行判断,switch只能对固定值进行判断。
switch的一些使用细节
switch所传入的变量,char,byte,short,int,String或者枚举类型
值1,值2,一直到值n,这几个值必须是同一个数据类型的
当变量匹配的相关case的值的时候,执行case中的语句,直到遇到break结束;如果该case语句
中没有break,则继续向下执行,直到遇到另外一个break结束
3.3 for循环语句
循环主要解决具有规律性的且具有重复性的代码问题,避免程序冗余
循环四要素
1循环的初始化:循环的第1次执行从哪里开始
2循环的继续条件:循环从当前轮是否向后执行下一轮
3循环体:需要被循环执行的部分
4循环的步长、周期:当前循环到下一轮循环之间的变化
我们常见的循环问题可以分为两大类:
已知循环次数的 一般用for语句做
未知循环次数但是已知循环结束条件 一般用while语句做
for (1循环的初始化;2.循环的继续条件;4.循环的步长) {
3.循环体
}
循环过程;1-2-3-4-2-3-4-2-3-4-2不满足则结束循环
3.4 while循环语句 while循环主要用于解决循环次数未知,但循环结束条件已知的情况。
while其实和for循环是可以相互转换的,是因为都逃不开循环四要素
while的语法格式
数字拆分求和
3.5 break、continue跳转语句
break在循环语句中叫做终止语句,终止的是break最近的一层循环
continue在循环语句中叫做跳过语句,跳过本次循环开启下一轮循环
跳转标签
3.6 编程练习题
课后作业
Demo17
Demo19
Demo21
Demo22
Demo25
思路; 先提示用户输入年月日,判断month是否为1或2;如果是month+12;年份-1;根据公式算出h的值;用h的值通过switch判断星期几
import java.util.Scanner;
public class Demo25 {
public static void main(String[] args){
Scanner input = new Scanner(System.in);
//先提示用户输入年月日
System.out.print(“Enter year: (e.g… 2012):”);
int year = input.nextInt();
System.out.print(“Enter month: 1-12:”);
int month = input.nextInt();
System.out.print(“Enter the day of the moth:”);
int day = input.nextInt();
//判断month是否为1或2;如果是month+12;年份-1;
if(month == 1){
month = 13;
year -= 1;
}else if(month == 2){
month = 14;
year -= 1;
}
//根据公式算出h的值;用h的值通过switch判断星期几
int h = (day + 26 * (month + 1) / 10 + year % 100 + (year % 100) / 4 + Math.abs(year/100) / 4 + 5 * Math.abs(year/100)) % 7;
switch(h) {
case 0:
System.out.print(“day of the week is Saturday”);
break;
case 1:
System.out.print("day of the week is Sunday ");
break;
case 2:
System.out.print("day of the week is Monday ");
break;
case 3:
System.out.print("day of the week is Tuseday ");
break;
case 4:
System.out.print("day of the week is Wednesday ");
break;
case 5:
System.out.print("day of the week is Thursday ");
break;
case 6:
System.out.print("day of the week is Friday ");
break;
}
}
}
Demo27
思路;提示用户输入坐标下x,y;/判断x&y的绝对值是否<1高/2&宽/2;如果小于;则输出在圆内;否则在圆外
import java.util.Scanner;
public class Demo27{
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
//提示用户输入坐标
System.out.print(“Enter a point with two coordinates:”);
double x = input.nextDouble();
double y = input.nextDouble();
//判断x&y的绝对值是否<1高/2&宽/2;如果小于;则输出在圆内;否则在圆外
if(( Math.abs(x) < 10/2) && (Math.abs(y) < 5.0 /2)){
System.out.print(“point " + x );
System.out.print(” " );
System.out.println( y + " is in the rectangle");
}else{
System.out.print(“point " + x );
System.out.print(”,");
System.out.println( y + " is not in the rectangle");
}
}
}
Demo29
第4章 常用类
4.1 Math类 Math类是用于数学计算的一个工具类
对于工具类而言,里面的大部分成员都是静态的static
自带常量
static double E:自然对数
static double PI:圆周率
取整方法
static double ceil(double a):向上取整
static double floor(double a):向下取整
static long round(double a):四舍五入
三角函数
static double sin(double a):正弦函数 参数是弧度值
static double cos(double a):余弦函数
static double tan(double a):正切函数
static double toDegrees(double a):将弧度转角度
static double toRadians(double angles):将角度转弧度
static double asin(double a):反正弦函数
static double acos(double a):反余弦函数
static double atan(double a):反正切函数
指数函数
static double pow(double a, double b):求a的b次幂
static double sqrt(double a):求a的平方根
static double cbrt(double a):求a的立方根
其他方法
static double abs(double a):求a的绝对值
static double hypot(double deltX, double deltY):返回 两点间距离
static double max(a,b):返回a和b之间的最大值
static double min(a,b):返回a和b之间的最小值
static double random():返回[0,1)之间的随机小数
public class Sample { public static void main(String[] args) { System.out.println(Math.E); System.out.println(Math.PI); System.out.println(Math.ceil(3.1)); System.out.println(Math.ceil(3.9)); System.out.println(Math.ceil(-3.1)); System.out.println(Math.ceil(-3.9)); System.out.println(Math.floor(3.1)); System.out.println(Math.floor(3.9)); System.out.println(Math.floor(-3.1)); System.out.println(Math.floor(-3.9));
4.2 Scanner类
主要用于负责数据输入的类,底层是和IO流相关。
String next():获取直到遇到空格为止的一个字符串
String nextLine():获取直到遇到回车为止的一个字符串
int nextInt():获取下一个整数 byte short long double nextDouble() boolean nextBoolean() float nextFloat() 4.3 Random类
主要用于产生随机数
boolean nextBoolean():随机产生布尔类型值
double nextDouble():随机生成0.0~1.0之间的小数
double nextInt():随机生成一个整数0~232的整数
double nextInt(n):随机生成一个整数[0,n)的整数 System.out.println(Math.round(3.1)); System.out.println(Math.round(3.9)); System.out.println(Math.round(-3.1)); System.out.println(Math.round(-3.9)); System.out.println(Math.sin(Math.PI/6)); System.out.println(Math.cos(Math.PI/3)); System.out.println(Math.tan(Math.PI/4)); System.out.println(Math.toDegrees(Math.PI/2)); System.out.println(Math.toRadians(90)); System.out.println(Math.cbrt(8)); System.out.println(Math.hypot(0 - 1, 0 - 1)); } }import java.util.Scanner; public class Sample { public static void main(String[] args) { Scanner input = new Scanner(System.in); System.out.print(“输入一句话:”); String line = input.nextLine(); System.out.println(line); System.out.print(“输入三个单词:”); String word1 = input.next(); String word2 = input.next(); String word3 = input.next(); System.out.println(word1); System.out.println(word2); System.out.println(word3); } }import java.util.Random; public class Sample { public static void main(String[] args) {
4.4 String类 String是一个类,它描述的是字符串。在Java代码当中,所有字符串常量(字符串字面量)都是
String类的一个实例对象。并且,字符串一旦创建,则不可修改! 不可修改其长度,不可修改其内容 。所
以将来对字符串内容的改变,不能在原地改,只能重新创建一个字符串。
获取相关
char charAt(int index):获取指定角标index处的字符
int indexOf(int ch):获取指定字符(编码)在字符串中第一次(从左到右)出现的地方返回的是
角标。如果是-1 表示不存在
int lastIndexOf(int ch):获取指定字符(编码)在字符串中第一次(从右到做)出现的地方返回的
是角标
int indexOf(String str):获取指定字符串在本字符串中第一次(从左到右)出现的地方返回的是
角标
int lastIndexOf(String str):获取指定字符串在本字符串中第一次(从右到左)出现的地方返回
的是角标
int length():获取字符串的长度(字符的个数)
String[] split(String regex):将字符串按照regex的定义进行切割(regex指的是正则表达式)
String substring(int beginIndex):截取一段子字符串,从beginIndex开始到结尾
String substring(int beginIndex, int endIndex):截取一段子字符串,从beginIndex开始到
endIndex(不包含)
判断相关
int compareTo(String anotherString):按照字典顺序比较两个字符串的大小
boolean contains(String another):判断当前字符串中是否包含指定字符串another boolean equals(String another):比较当前字符串与指定字符串的内容是否相同
boolean isEmpty():判断当前字符串是否为空,length() == 0 boolean startsWith(String prefix):判断该字符串是否以prefix开头
boolean endsWith(String suwix):判断该字符串是否已suwix结尾
Random random = new Random();
for (int i = 1; i <= 10; i++) { System.out.print(random.nextBoolean() + " "); }System.out.println();
for (int i = 1; i <= 10; i++) { System.out.print(random.nextInt(2) + " "); }System.out.println();
for (int i = 1; i <= 10; i++) { System.out.print(random.nextInt() + " “); }System.out.println(); } }public class Sample { public static void main(String[] args) { String s1 = “abc”; String s2 = “ab” + “dc”; //上述代码一共有几个字符串? //四个"abc” “ab” “dc” “abdc” } }
修改相关
String toLowerCase():将字符串中所有的英文字母全部变为小写
String toUpperCase():将字符串中所有的英文字母全部变为大写
String trim():将字符串中两端的多余空格进行删除
String replace(char oldCh,char newCh):将字符串中oldCh字符替换成newCh字符
4.5 Character类 Character它是char基本数据类型的 包装类 ,有这么几个静态方法我可目前可以使用到的
}public class Sample { public static void main(String[] args) { //最好的算法KMP算法 String s1 = “abcbcbcbcbcbc”; String s2 = “bcb”; //贪心算法 5个 int count = 0;
for (int i = 0; i < s1.length() - s2.length() + 1; i++) { if (s1.charAt(i) == s2.charAt(0)) { if (s2.equals(s1.substring(i,i + s2.length()))) { count++; } } }System.out.println(count); //非贪心算法 3个 /*String temp = s1; int count = 0; while (true) { int index = temp.indexOf(s2); if (index == -1) { break; }count++; temp = temp.substring(index + s2.length()); }System.out.println(count); / } }public class Sample { public static void main(String[] args) { String s1 = “c is a program but is diffcult”; String s2 = “Java is a program but is slow”;
for (int len = s2.length(); len > 0; len–) {
for (int l = 0,r = len - 1; r < s2.length(); l++,r++) { String temp = s2.substring(l,r + 1); if (s1.contains(temp)) { System.out.println(temp); return;//直接结束程序 } } } } }
static boolean isDigit(char ch):判断字符是否是数字
static boolean isLetter(char ch):判断字符是否是字母
static boolean isLetterOrDigit(char ch):判断字符是否是数字或字母
static boolean isLowerCase(char ch):判断是否是小写字母
static boolean isUpperCase(char ch):判断是否是大写字母
static boolean isSpaceChar(char ch):判断是否空白字母(空格 制表符 回车)
将十六进制数字转为十进制
4.6 编程练习题
课堂演示
Demo53
课后作业
Demo55 Demo57
思路;提示用户输入n条边和边长s,通过题中所给公式算出面积
import java.util.Scanner;
public class Demo57 {
public static void main(String[] args) {
//提示用户输入n条边和边长s
Scanner input = new Scanner(System.in);
System.out.print(“n:”);
double n =input.nextDouble();
System.out.print(“s:”);
double s =input.nextDouble();
//通过题中所给公式算出面积
double area = (n * ss ) /(4 * Math.tan(Math.PI / n));
System.out.print(“The area of the pentagon is” + area);
}
}
Demo58
思路;先设置变量 int num 为用户输入数字;
设置变量ASCII, 将num由inte类型转换为char类型=ASCII;输出ASCII;
import java.util.Scanner;
public class Demo58 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
//提醒用户输入
System.out.print(“Enter the number of sides:”);
int num = input.nextInt();
//将num由inte类型转换为char类型
char ASCII = (char)num;
System.out.print(“The character for ASCII code " + num +” is " +ASCII);
}
}
Demo62
思路;输入字符串,建立新的空字符串;建立for循环用角标来查寻字符,加到空字符串的前面
import java.util.Scanner;
public class Demo60 {
public static void main(String[] args){
Scanner input = new Scanner(System.in);
System.out.print(“Enter a string :”);
String a = input.nextLine();
String arr = " ";
for( int i =0;i < a.length();i++){
arr = a.charAt(i) +arr;
}
System.out.print("The revesed string is " + arr);
}
}
Demo64
思路;输入字符串;建立for循环
用if判断i%2是否为1;为1输出角标i处的字符
import java.util.Scanner;
public class Demo64 {
public static void main(String[] args){
Scanner input = new Scanner(System.in);
System.out.print("Enter a string: ");
String arr = input.nextLine();
for(int i =0;i< arr.length();i++){
if(i %2 == 1){
System.out.print(arr.charAt(i));
}
}
}
}
Demo65
思路;输入字符串;建立for循环
用if判断角标i处的字符是否为大写字母;如果是,count++;
最后打印count
5.1 函数的概念
什么是函数
函数的定义就是指一段具有独立功能的代码,减少代码冗余,提高程序的利用率和效率。
我们应该如何去定义函数呢?
需要一个封闭的空间,将这段独立性的代码进行封装,用一对大括号
需要对每一个封闭的空间进行命名,函数名
函数所需要的一些原始数据
函数所产生的一些结果数据
函数的语法格式
System.out.print(“Enter s1:”); String s1 = input.nextLine(); System.out.print(“Enter s2:”); String s2 = input.nextLine(); /* 123456123 123456i */if (s1.charAt(0) != s2.charAt(0)) { System.out.println(“none”); return; }boolean flag = true;
for (int i = 0; i < s2.length(); i++) { if (s1.charAt(i) != s2.charAt(i)) {
flag = false; System.out.println(s2.substring(0,i)); break; } }if (flag) { System.out.println(s2); } } }
修饰符 函数类型 返回值类型 函数名(数据类型 数据1,数据类型 数据2,…) { 独立功能的代码片段; return 函数的计算结果; }
修饰符:指的是函数的访问权限,public private 默认 protected
函数类型:函数的分类,本地函数native,静态函数static,同步函数 synchronized
返回值类型:指的就是函数计算结果的数据类型 如果函数没有返回值 则为void
函数名:就是函数的名称
参数列表:指的是外界向函数传入的数据(实际参数),由这些参数变量进行接收(形式参
数)
函数体:具有独立功能的代码片段;
return:仅仅表示函数结束!如果函数有返回值,则return后跟返回值;如果没有返回值,则
return可以不写,但是是存在的(隐藏的 在最后一行)
根据形参和返回值来看,函数有如下几个分类
有参数有返回值
求三个数字当中的最大值
public class Sample { public static void main(String[] args) { int max = getMax(1,2,3); System.out.println(max); }public static int getMax (int a , int b , int c) { /if (a >= b && a >= c) { return a; }else if (b >= a && b >= c) { return b; }else { return c; }/if (a >= b && a >= c) { return a; }if (b >= a && b >= c) { return b; }if (c >= a && c >= b) { return c; }return -10000; } }
计算一个数字a的b次幂
public class Sample { public static double pow (double a , int b) { if (a == 0) { return 0; }if (b == 0) { return 1;
}double result = 1.0;
for (int i = 0; i < Math.abs(b) ; i++) { result *= a; }return b > 0 ? result : 1 / result; }public static void main(String[] args) { System.out.println(pow(2,2)); System.out.println(pow(2,-3)); } }
有参数没返回值
将三个字符串的反转,并拼接打印
public class Sample { public static void main(String[] args) { print(“123”,“456”,“789”); }//123 456 789 =? 321654987 public static void print(String s1 , String s2 , String s3) { System.out.println(reverse(s1) + reverse(s2) + reverse(s3)); }public static String reverse(String s) { String res = “”;
for (int i = s.length() - 1; i >= 0; i–) { res += s.charAt(i); }return res; } }
没参数有返回值
获取当前时间的字符串
public class Sample { public static void main(String[] args) { String currentTime = getTime(); System.out.println(currentTime); }public static String getTime() { //1.获取总毫秒数 long millis = System.currentTimeMillis(); //2.计算总秒数 long seconds = millis / 1000; //3.计算总分钟数 long minutes = seconds / 60; //4.计算总小时数 long hours = minutes / 60; //5.计算当前小时数 long currentHours = hours % 24; //6.计算当前分钟数 long currenrMinutes = minutes % 60;
没参数没返回值
总结定义函数时需要考虑的有哪些?
函数的运行有哪些未知的参数?
函数的运行结果有是什么?
明确参数和结果
明确内容和返回
函数到底要干什么?尽量将独立功能且重复性较高的代码片段提取出来
5.2 函数的运行原理
函数的运行是基于栈运行的
栈:是一种先进后出的容器,我们这里面所说的栈是指JVM中的栈内存空间
每一个函数,叫做栈帧,栈帧中所包含的内容有函数的定义,参数列表,函数的执行内容代码
每一个函数要运行,就相当于这个栈帧进入到栈内存中-入栈
如果一个函数即将结束,将这个栈帧从栈顶移出-出栈
//7.计算当前秒数 long currentSeconds = seconds % 60; return currentHours + “:” + currenrMinutes + “:” + currentSeconds; } }public class Sample { public static void main(String[] args) { getTime(); }public static void getTime() { //1.获取总毫秒数 long millis = System.currentTimeMillis(); //2.计算总秒数 long seconds = millis / 1000; //3.计算总分钟数 long minutes = seconds / 60; //4.计算总小时数 long hours = minutes / 60; //5.计算当前小时数 long currentHours = hours % 24; //6.计算当前分钟数 long currenrMinutes = minutes % 60; //7.计算当前秒数 long currentSeconds = seconds % 60; System.out.println(currentHours + “:” + currenrMinutes + “:” + currentSeconds); } }
如果栈内存中有多个栈帧,运行的是最上面的栈帧,底下的栈帧暂停运行,直到该栈帧为栈顶元素
比如:主函数先进栈,开始逐行运行,如果执行到第n行,调用另外一个函数A,则主函数在第n行
暂停运行,将另一个函数A的栈帧入栈,再继续逐行运行,直到函数A的内容执行完毕,函数A出栈,主
函数接着从第n行继续向下执行。以此类推。
public class Sample { public static void main(String[] args) { int a = 10; int b = 20; String s1 = “123”; String s2 = “456”; int c = test1(a,b); System.out.println(a); System.out.println(b); System.out.println©; String s3 = test2(s1,s2); System.out.println(s1); System.out.println(s2); System.out.println(s3); }public static int test1(int a, int b) { a = 20; b = 30; return a + b; }public static String test2(String s1, String s2) { s1 = s1.replace(“1”,“hehe”); s2 = s2.replace(“4”,“heihei”); return s1 + s2; } }
5.3 函数重载
同一个类中可以出现多个同名函数,这个现象就叫做函数的重载(overload)
如何来区分同名函数是否是重载关系呢?前提必须是同名,和返回值类型无关(返回值类型只和函
数的计算功能相关),和权限也没有关系,和形式参数的名称也无关!只和形式参数的数据类型有关
(数量,排列组合)
下列哪些是该函数的重载:
int show(int x, float y, char z) :不算重载 数据类型都是int float char void show(float b,int a,char c):算重载,顺序不一样float int char void show(int a,int b,int c):算重载,顺序不一样int int int double show():算重载,参数不一样
寻找重载函数的流程:
- 看是否有确切的参数定义匹配,int int 找 int int 2. 看是否有可兼容的参数定义匹配,int int找double double或int double或double int 3. 如果可兼容的参数定义匹配较多,会报引用确定报错 引用不明确
5.4 函数的递归
函数的递归就是指函数自身调用自身。
人用迭代,神用递归
但凡迭代能够解决的问题,递归都可以解决;递归能够解决的问题,迭代就不一定了
相对而言,从内存的角度而言,函数如果过多的自我调用,势必会对内存不友好,占用过多
通常来讲,同样的问题用递归写要比用迭代写代码量较少
写递归时,一定要先确定递归结束条件-递归边界
什么情况下可以使用递归?迭代的,数学归纳法的问题
public static void show(int a ,float b ,char c){} public class Sample { public static void main(String[] args) { //show(); //无限递归
test(10); }public static void test(int n) { System.out.println(n); if (n == 1) { return; } else { test(n - 1); } }public static void show() { System.out.println(“Hello!”); show(); } }
用递归实现1+2+…+99+100 import java.util.Scanner; public class Sample { /* String s = “123”; System.out.println(s.charAt(7)); //StringIndexOutOfBoundsException *//*System.out.println(10/0); //ArithmeticException *//*Integer.parseInt(“789abc”); //NumberFormatException *//*Scanner input = new Scanner(System.in); int number = input.nextInt(); //InputMismatchException */public static void main(String[] args) { System.out.println(f(100)); //System.out.println(f(10000000));//StackOverflowError int sum = 0;
for (int i = 1; i <= 10000000; i++) { sum += i; }System.out.println(sum); }/*求1+2+…+99+100 设函数f(x) = 1 + 2 + 3 + … + x-3 + x-2 + x-1 + x
f(3) = 1 + 2 + 3
f(2) = 1 + 2
f(3) = f(2) + 3 => 1 ,x = 1
f(x) =
f(x-1) + x , x>1
f(x) = f(x- 1) + x
f(100) = f(99) + 100 1+2+3+…+99 + 100
f(99) = f(98) + 99 1+2+3+…+98 + 99 …
f(4) = f(3) + 4 1+2+3 + 4
f(3) = f(2) + 3 1+2 + 3
f(2) = f(1) + 2 1 + 2
f(1) = 1 递归的边界 */public static int f(int x) { if (x == 1) { return 1; } else { return f(x - 1) + x; } } }
递归实现斐波那契数列
public class Sample { public static void main(String[] args) { /*1 1 2 3 5 8 13 21 34 55 … 1 x=1,x=2
f(x) =
f(x-1) + f(x-2) x>2
f(5)
f(4) f(3)
f(3) f(2) f(2) f(1)
f(2) f(1) *///递归O(2^n) System.out.println(f(35)); //迭代O(n) System.out.println(fibo_it(35)); }public static int fibo_it(int x) { if (x == 1 || x == 2) { return 1; }/*1 1 2 3c a b */int a = 1; int b = 1; int c = 0;
for (int i = 3; i <= x; i++) { c = a + b; a = b; b = c; }return c; }
5.5 编程练习题
课堂练习
Demo67 Demo68 Demo70
public static int f(int x) {
if (x == 1 || x == 2) {
return 1; }else { return f(x-1) + f(x-2);
} } }
public class Demo67 {
public static void main(String[] args) { System.out.println(sumDigits(123)); System.out.println(sumDigits(6969696969696969L));
}public static int sumDigits(long n) {
int sum = 0;
while (n != 0) {
sum += n % 10;
n /= 10;
}return sum;
} }import java.util.Scanner;
public class Demo68 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in); System.out.print(“Enter a number:”);
int number = scanner.nextInt(); System.out.println(isPalindrome(number));
}
public static boolean isPalindrome(int number) {
int revNumber = reverse(number);
return number == revNumber;
}
public static int reverse(int number) {
int result = 0;
while (number != 0) {
result = result * 10 + number % 10;
number /= 10; }return result;
} }
import java.util.Scanner;
public class Demo70 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in); System.out.print(“Enter a password:”);
String password = input.nextLine();
if (condition1(password) && condition2(password) && condition3(password)) {
System.out.println(“valid!”);
} else {
System.out.println(“invalid!”);
} }
public static boolean condition1(String password) {
return password.length() >= 8;
}public static boolean condition2(String password) {
for (int i = 0; i < password.length(); i++) { char c = password.charAt(i); /if (!Character.isLetterOrDigit©) {
return false;
}/if (!isLetter© || !isDigit©) { return false; } }return true; }public static boolean condition3(String password) { int count = 0;
for (int i = 0; i < password.length(); i++) { char c = password.charAt(i); if (isDigit©) { count++; } }return count >= 2; }public static boolean isLetter(char c) { return c >= ‘a’ && c <= ‘z’ || c >= ‘A’ && c <= ‘Z’; }public static boolean isDigit(char c) { return c >= ‘0’ && c <= ‘9’; } } Demo73 public class Demo73 { public static void main(String[] args) { System.out.println(sqrt(4)); System.out.println(sqrt(9)); System.out.println(sqrt(2)); }public static double sqrt(long n) { double lastGuess = 1; double nextGuess = 0; while (true) {
nextGuess = (lastGuess + n / lastGuess) / 2; if (Math.abs(lastGuess - nextGuess) > 0.0001) { lastGuess = nextGuess; } else { break; } }return nextGuess; } } Demo74 public class Demo74 { public static void main(String[] args) { int number = 2; int count = 0; while (count < 100) { if (isSuShu(number) && isHuiWen(number)) { System.out.print(number + “\t”); count++; if (count % 10 == 0) { System.out.println(); } }number++; } }public static boolean isHuiWen(int number) { int revNumber = reverse(number); return revNumber == number; }public static int reverse(int number) { String str = “”; while (number != 0) { str = str + number % 10; number /= 10; }return Integer.parseInt(str); }public static boolean isSuShu(int number) {
for (int i = 2 ; i <= number / 2; i++) { if (number % i == 0) { return false; } }return true; } } Demo76 public class Demo76 { public static void main(String[] args) {
for (int p = 2; p <= 31; p++) { int number = (int)Math.pow(2,p) - 1; if (isSuShu(number)) { System.out.println(“p = " + p + “, sushu = " + number);
} } }public static boolean isSuShu(int number) {
for (int i = 2 ; i <= number / 2; i++) { if (number % i == 0) { return false; } }return true; } } Demo80 Demo81 public class Demo81 { /*前4个 x->z 前3个 x->y 前2个 x->z 前1个 x->y 第2个 x->z 前1个 y->z 第3个 x->y 前2个 z->y 前1个 z->x 第2个 z->y 前1个 x->y 第4个 x->z 前3个 y->z 前2个 y->x 前1个 y->z 第2个 y->x 前1个 z->x 第3个 y->z 前2个 x->z 前1个 x->y 第2个 x->z 前1个 y->z */public static void main(String[] args) { String x = “x”; String y = “y”; String z = “z”; hano(3,x,y,z); //前3层从 x->z //前2层从 x->y }public static void hano(int level,String begin,String mid,String end) { if (level == 1) { System.out.println(begin+”->”+end); } else { //前level-1层 hano(level - 1,begin,end,mid); System.out.println(begin+"->"+end); //前leve1-1层 hano(level - 1,mid,begin,end);
课后作业
Demo69 Demo71 Demo72 Demo75 Demo77 Demo78 Demo79 第6章 数组
6.1 数组的概念及定义
数组主要用于解决大量数据计算与存储的问题
比如:输入100个数字,统计其中的最大值和最小值并计算平均值,创建100个变量,会有一堆if- else语句,比较麻烦。
数组是Java提供的一种最简单的数据结构,可以用来存储一个元素 个数固定 且 类型相同 的有序
集。
数组在内存中的情况
栈:主要用于运行函数的内存
堆:主要用于存储数据对象的内存
每一个数组而言,都是存在堆内存当中,每一个数组都是一个对象
} } }
数组本质上就是在堆内存中一系列地址连续且空间大小相等的存储空间(变量),每一个存
储空间用来存储数据(基本,引用)
数组是在堆内存中存储,称之为是一个对数对象,并且在堆内存中存储的数据都有 默认初始 化 的流程。所以数组创建之初,每一个存储空间里面都会被JVM初始化该数据类型对应的零值。
数组的地址是连续的,所以通过公式:An=A1+(n-1)*d可以快速访问到其他的元素,所以对于
数组而言查找元素比较快的。将元素的真实物理地址转换成对应的角标获取元素。
如何来调用数组呢?通过一个变量存储该数组在堆内存当中的首元素的地址。
当数组一旦定义出来,其长度不可变,存储空间的内容是可变的
所以我们在定义数组的时候,要么把长度固定,要么直接输入相关的元素。
数组的定义方式
//创建一个指定长度且指定数据类型的一维数组,名称为数组名,虽然没有指定元素,但是会有默认值 数据类型[] 数组名 = new 数据类型[长度]; //创建一个指定元素且指定数据类型的一维数组,名称为数组名,虽然有指定元素,还是有默认初始化这个步骤的! 数据类型[] 数组名 = new 数据类型[]{数据1,数据2,…,数据n}; 数据类型[] 数组名 = {数据1,数据2,…,数据n}; public class Sample { public static void main(String[] args) { int[] arr = new int[5]; System.out.println(arr[0]); //System.out.println(arr[5]); //ArrayIndexOutOfBoundsException arr[2] = 10; int[] arr2 = arr; System.out.println(arr2[2]); arr2 = null; //System.out.println(arr2[2]); //NullPointerException /String s = null; s.length(); /arr = null; } }
6.2 常用数组操作
数组遍历问题
数组最值问题
数组扩容问题
public class Sample { public static void main(String[] args) { int[] arr = new int[]{1,2,3,4,5,6,7,8,9}; //String str str.length()-函数 //int[] arr arr.length-属性
for (int i = 0; i < arr.length; i++) { arr[i] = arr[i] * 10; System.out.println(arr[i]); }//通过角标遍历 可以在遍历的过程中对指定的元素进行修改 //foreach遍历 主要针对的是一些可迭代对象 Iterable /
for (数据类型 变量名 : 可迭代容器) { }/
for (int num : arr) { //num -> arr[i] num = num / 10; System.out.println(num); }//这种遍历方式 只能获取元素,不能修改元素
for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); } } }public class Sample { public static void main(String[] args) { int[] arr = new int[]{3,6,8,2,9,4,5,1,7}; int min = arr[0]; int max = arr[0];
for (int i = 1; i < arr.length; i++) { if (arr[i] < min) { min = arr[i]; }if (arr[i] > max) { max = arr[i]; } }System.out.println(max); System.out.println(min); } }public class Sample { public static void main(String[] args) { int[] arr = new int[]{1,2,3,4,5};
arr = add(arr,6); arr = add(arr,6); arr = add(arr,6); arr = add(arr,6);
for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); } }//在指定的数组arr中添加元素element public static int[] add(int[] arr, int element) { int[] newArr = new int[arr.length + 1];
for (int i = 0; i < arr.length; i++) { newArr[i] = arr[i]; }newArr[newArr.length - 1] = element; return newArr; } }
选择排序算法
public class Sample { //选择排序 public static void main(String[] args) { int[] arr = {8,9,2,6,7,1,4,5,3};
for (int i = 0; i < arr.length - 1; i++) { //-1 n个数字没有第n轮
for (int j = i + 1; j < arr.length; j++) { if (arr[i] > arr[j]) { swap(arr,i,j); } } }print(arr); }//[1, 2, 3, 4, 5] public static void print(int[] arr) { System.out.print("[");
for (int i = 0; i < arr.length;i++) { System.out.print(arr[i]); if (i == arr.length - 1) { System.out.println("]"); } else {
System.out.print(", “); } } }public static void swap(int[] arr, int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } }
冒泡排序算法
public class Sample { //冒泡排序 public static void main(String[] args) { int[] arr = {8,9,2,6,7,1,4,5,3};
for (int i = 0; i for (int j = 0; j < arr.length - 1 - i; j++) {//-1 避免重复比较(当前最大和上一 轮最大) if (arr[j] > arr[j + 1]) { swap(arr,j,j+1); } } }print(arr); }public static void print(int[] arr) { System.out.print(”[");
for (int i = 0; i < arr.length;i++) { System.out.print(arr[i]); if (i == arr.length - 1) { System.out.println("]"); } else { System.out.print(", “); } } }public static void swap(int[] arr, int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } }
插入排序算法
public class Sample { //插入排序 public static void main(String[] args) { int[] arr = {8,9,2,6,7,1,4,5,3};
for (int i = 1; i < arr.length; i++) { int e = arr[i]; int j = 0;
for (j = i; j > 0 && arr[j - 1] > e; j–) { arr[j] = arr[j - 1]; }arr[j] = e; }print(arr); }public static void print(int[] arr) { System.out.print(”[");
for (int i = 0; i < arr.length;i++) { System.out.print(arr[i]); if (i == arr.length - 1) { System.out.println("]"); } else { System.out.print(", “); } } } }
计数排序算法
public class Sample { //计数排序 public static void main(String[] args) { int[] arr = {-2,9,-1,12,8,-3,6,7,4,5,2,1,0,8,6,7,4,-3,-2,-1,-1,7}; int min = arr[0];
int max = arr[0]; //O(n)
for (int i = 1; i < arr.length; i++) { if (arr[i] < min) { min = arr[i]; }if (arr[i] > max) { max = arr[i]; } }int[] temp = new int[max - min + 1]; //对应关系 index = number - min number = index + min //O(n)
for (int i = 0; i < arr.length; i++) { temp[arr[i] - min]++; }//temp[index] 表示index对应的数字number出现的次数 int k = 0; //O(n)
for (int index = 0; index < temp.length; index++) { while (temp[index] != 0) { arr[k] = index + min; k++; temp[index]–; } }print(arr); }public static void print(int[] arr) { System.out.print(”[");
for (int i = 0; i < arr.length;i++) { System.out.print(arr[i]); if (i == arr.length - 1) { System.out.println("]"); } else { System.out.print(", “); } } } }
基数排序算法
import java.util.LinkedList; public class Sample { //基数排序 public static void main(String[] args) { int[] arr = {102,203,321,13,12,78,96,34,37,28,6,8,5,6}; //1.先找到最大值 决定轮数 int max = arr[0];
for (int i = 0; i < arr.length; i++) { if (arr[i] > max) { max = arr[i]; } }int radex = (max + “”).length(); //2.创建十个桶 每一个桶是LinkedList LinkedList[] queues = new LinkedList[10];
for (int i = 0; i < queues.length; i++) { queues[i] = new LinkedList(); }//3.进行数字分类和规整 //r=0个位 r=1十位 r=2百位…
for (int r = 0; r < radex; r++) { //先按照r进行分类
for (int i = 0; i < arr.length; i++) { int index = getIndex(arr[i],r);//获取数字的r位 返回该数字要去的桶的角标0~9 queues[index].offer(arr[i]);
}//然后在重新规整到arr里 int k = 0;
for (int index = 0; index < queues.length; index++) { while(!queues[index].isEmpty()) {
arr[k++] = queues[index].poll();
}
}
}
print(arr);
}
public static int getIndex(int number, int r) {
//123 r=0 //123 r=1 //123 r=2 int index = 0;
for (int i = 0; i <= r; i++) {
index = number % 10;
number /= 10;
}return index;
}public static void print(int[] arr) {
System.out.print(”[");
for (int i = 0; i < arr.length;i++) {
System.out.print(arr[i]); if (i == arr.length - 1) { System.out.println("]"); } else {
System.out.print(", "); } } } }
二分查找算法
有一个前提,所查找的数据集必须是有序的(升序,降序)
public class Sample {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6,7,8,9};
int min = 0;
int max = arr.length - 1;
int mid = (min + max) / 2;
int key = 10; while (arr[mid] != key) {
if (key < arr[mid]) {
max = mid - 1;
}if (arr[mid] < key) {
min = mid + 1; }if (min > max) {
mid = -1; break; }mid = (min + max) / 2; }System.out.println(mid); } }
可变长参数列表
6.3 二维数组 6.4 编程练习题
课堂演示
public class Sample {
public static void main(String[] args) {
show(1);
show(1,2,3);
show(“hehe”,“lala”,“haha”,“xixi”,“heihei”);
}public static void show(int … nums) {
for (int i = 0; i < nums.length; i++) {
System.out.print(nums[i] + " ");
}System.out.println();
}public static void show(String … strs) {
for (int i = 0; i < strs.length; i++) {
System.out.print(strs[i] + " ");
}System.out.println();