知识点 | 链接 |
---|---|
配置环境变量 | 手把手教你配置Java环境变量 |
Hello world | 我的第一个Java Hello world程序 |
参考视频:
韩顺平java基础
1、Java简述
Java有什么用?
Java的应用
- 安卓平台开发
- web
- SSM
- 大数据
- …
Java历史是怎样的?
版本
- 1995年,出现java 1, 到 Java8是较大的更新,最近版本是 Java 11,两者都是企业常用的
技术体系
- JavaSE、也可称为Java基础,也是Java的核心—-面向桌面
- JavaEE、称为Java高级,面向企业级web开发
- JavaME, 小型移动应用(被安卓替代)
Java有哪些特性?
跨平台性
- JVM (Java虚拟机)
- 编程语言的分类 : ①编译型执行,②解释执行
JDK 是什么?
- Java Development Kit ( Java开发包 )
组成
JDK
JRE
JVM
Java核心类库
Java开发工具
安装 JDK
步骤:
1、下载JDK :
2、安装JDK :
3、配置环境变量: 手把手教你配置Java环境变量
4、第一个Java程序 (Hello World) : 我的第一个Java Hello world程序
Java参考学习路线图
Java快速入门
【Demo-01】: 创建第2个Java程序,从控制台接受用户输入的数据,打印到控制台
// 导入 Scannner类
import java.util.Scanner;
/**
* @author Martin
* @create $2021-02-17-20:26
* 测试 Scanner接受用户输入
**/
// ------------------创建测试类------------------------------------
public class Test {
public static void main(String[] args) {
//创建 Scanner对象
Scanner scanner = new Scanner(System.in);
// 提示用户输入
System.out.println("请输入您的姓名: ");
// 接受用户输入的一行
String userName = scanner.nextLine();
// 向控制台输出
System.out.println(userName+"你好!,恭喜您进入Java学习的大门");
}
}
CODE-OUT
请输入您的姓名:
Martin
Martin你好!,恭喜您进入Java学习的大门
Java开发注意事项和细节
- Java源文件扩展为
.java
,基本组成是类(class
) - Java应用程序入口是
main( )
方法 - Java严格区分
大小写
- Java由一条条语句构成,语句以
;
结尾 - 若源文件名含
public
类,则以该类名作为文件名 - 可将
main()
方法写到非 Public
类中,可指定运行非Public
类
如何快速学习一门技术?
定位工作需求
- 工作需求,兴趣爱好
- 尝试用已学知识解决,对比中学习,引出要学习的知识点
- 学习新技术的知识点的基本原理和语法 (不要钻牛角尖)
- 制作快速入门Demo程序,创建基本案例,用
代码表达思想
- 研究注意事项和使用规范,找出难点和重点
注释
1、单行注释
// 注释文字
2、多行注释
/*
注释文字
*/
3、文档注释
参考视频: 点我访问
基本格式:
/**
*文档说明
*
*/
如
/**
*@author Martin
*@version 1.0
*
*/
作用:
注释内容可被 JDK提供的工具 JavaDoc 解析,生成说明文档,以网页形式体现该程序的
javadoc -d 文件夹名 -xx -yy xxx.java
使用:
1、准备用于输出的文件夹,如 D:\temp
2、执行 javadoc 命令
Java代码规范
- 类,方法的注释,使用javadoc方式写
- 非 Java Doc注释,是给维护者看的,说明清楚 原因,如何修改,注意问题等
- 使用 Tab缩进补齐
运算符
和=
之间有空格,如int a = 1;
,而不是int a=1;
- 源文件使用
UTF-8
编码 - 单行宽不超过
80
个字符 - 代码编写风格
次行风格
和行尾风格
绝对路径和相对路径
DOS常用命令
进制转换
进制的转换是基本功,务必掌握
分为四组
2,8,16进制—->十进制**
1、二进制转10进制
规则 : 从最低位(最右边)开始,将每个位上的数提出来,乘以2的(位数-1)次方,然后求和
案例 : 请将0b1010二进制转换为10进制数
2、将八进制转化为10进制
规则 : 从最低位(最右边)开始,将每个位上数提取出来,乘以8的(位数-1)次方,然后求和
案例: 请将0234转成十进制
3、16进制=>10进制
略
十进制—->2,8,16进制
1、十进制转2进制
规则 : 十进制数除2,依次将余数从 最低位到最高位排列 ,得出的数字就是该十进制数二进制表示
案例 : 请将 34转为二进制
10=>8,16略
位运算
基本概念: 原码,反码,补码
位运算基本规则:
- 1、二进制最高位是
符号位
:0
表示正数,1
表示负数 (记忆,1->-1,0->0) - 2、
正数
原码,反码,补码一样 (三码合一
) - 3、负数反码 = 其原码符号位不变,其他位
按位取反
- 4、
负数补码
= 其反码 + 1, 负数反码 = 其补码 - 1 - 5、0的反码,补码都是 0
- 6、Java没有
无符号数
- 7、计算机
运行
时,都是以补码
形式运算
- 8、运算
结果
是 以原码
展现
【案例】
// ------------------创建测试类------------------------------------
public class Test {
/*
学习位运算知道几种 运算规则
java中的7个运算符 ( &,|,^,~,>>,<<,>>>)
1、按位与 & 两位全为1,结果为1,否则为0
2、按位或 | 两位有一个为1,结果为1,否则为0
3、按位异或 ^ 两位一个为1,一个为0,结果为1,否则为0
4、按位取反 ~ 0变为1,1变为0
案例 :
2&3 = ? , ~-2 = ? ,~2 = ? , 2|3 = ?, 2^3 =?
*/
public static void main(String[] args) {
/*
1.先得到2的补码
2的原码 00000000 000000000 00000000 00000010
2的补码 00000000 000000000 00000000 00000010
2.得到3的补码
3的原码 00000000 000000000 00000000 00000011
3的补码 00000000 000000000 00000000 00000011
3. 2&3 运算
00000000 000000000 00000000 00000010
00000000 000000000 00000000 00000011
&运算后 = 00000000 000000000 00000000 00000010
4.&运算后的原码也是(因为正数) 00000000 000000000 00000000 00000010
结果是 2
*/
System.out.println("2&3的结果是: "+(2&3)); // 2&3的结果是: 2
/*
1. 先得到 -2 的原码 10000000 00000000 00000000 00000010
2. 得到 -2 的反码 11111111 11111111 11111111 11111101
3、-2的补码 11111111 11111111 11111111 11111110
4. ~-2 运算操作后的补码 0000000 00000000 00000000 00000001
5.运算后的原码是 0000000 00000000 00000000 00000001
6.结果是 1
*/
System.out.println("~-2的结果是: "+(~-2)); //~-2的结果是: 1
}
}
/*
-------------------运行结果-----------
2&3的结果是: 2
~-2的结果是: 1
*/
【案例】: 测试 位运算符 >>
,<<
// ------------------创建测试类------------------------------------
public class Test {
public static void main(String[] args) {
/*
运算符号 >> , << , >>>
>> : 算术右移 , 低位溢出,符号位不变,用符号位补溢出的高位
<< : 算术左移 , 符号位不变,低位补0
>>> : 逻辑右移或无符号右移 ,低位溢出,高位补0
Tips : 没有 <<< 符号
案例 :
int a = 1>>2 ;
1-> 00000001 -> 00000000 本质 1/2/2 = 0
int c = 1<<2 ;
1-> 00000001 -> 00000100 本质 1*2*2 = 4
*/
int a = 1>>2;
System.out.println("a的值是:"+a);//0
}
}
/*
-------------------运行结果-----------
a的值是:0
*/
小练习
1 练习 :
2 1.计算下列表达式的结果
3 10/3=3 ; 10/5=2 ; 10/2=0 ; -10.5%3=?
4
5 a%b 当a是小数,公式 = a-(int)a/b*b
6 -10.5%3 = -10.5-(-10)/3*3 = -10.5+9 = -1.5
7
8 Tips :有小数运算的结果是 近似值
9
10 2.在java中,下列赋值语句正确的是( )
11 A). int num1 - (int)"18"; //错误 字符串强转int用 integer.parseInt("18")
12 B). int num2 = 18.0 ; // double类型强转int ,精度缺失
变量
变量的基本原理
变量 即
变化
的值- 变量 用于
表示
内存中一个数据储存空间 (房间的门牌号) - 值 是 内存空间储存的数据 (房间中的内容)
- 变量 用于
为什么需要变量?
- 变量名的本质: 一段内存的
地址
,使用变量作用是方便程序员调用
声明变量
//格式
变量类型 变量名;
//实例
int a ; // 表示声明一个 int 类型 a 变量
变量赋值
//格式
变量名 = 值;
//实例
a = 1; //表示将一个 int 类型值 1赋值给变量所在的内存空间
【案例】 使用变量,记录人的信息
// ------------------创建测试类------------------------------------
public class Test {
public static void main(String[] args) {
//创建变量并 赋值
int age = 20;
double score = 88.8;
String name = "张三";
char gender = '男';
// 输出信息
System.out.println("人的信息如下: ");
System.out.println(name);
System.out.println(age);
System.out.println(score);
System.out.println(gender);
}
}
/*
-------------------运行结果-----------
人的信息如下:
张三
20
88.8
男
*/
变量使用注意事项:
- 变量 表示
内存
中的一段储存空间
,不同变量,类型不同,储存空间大小不同 (如 int 占 4个字节,double 占8个字节) - 变量 必须
先声明
后使用 储存空
间 中值可在类型范围
内变化
程序中 +
号的使用:
// 如果 + 两边都是 数值,则 按加法运算
System.out.println(100+98); // 结果 1198
// 如果 + 一方有字符串,则做拼接操作
System.out.println("100"+98); //10098
数据类型
基本数据类型: byte,short,int,long,float,double,char,boolean (8种)
整数类型
bit和byte
bit: 基本单位
byte: 最小单位
浮点类型
浮点型的分类:
类型 | 占用储存空间 | 范围 |
---|---|---|
单精度 float | 4 字节 | -3.403E38 ~ 3.403E38 |
双精度 double | 8 字节 | -1.798E308 ~ 1.798E308 |
浮点数 = 符号位+指数位+尾数位
注意事项:
java
默认浮点型
常量 为double
,如声明 float型常量,需加 ‘f
‘ 或 ‘F
‘浮点型常量有
两种
表示形式: ①十进制数
,如 5.12,②科学计数法
,如5.12e2,5.12E-2浮点数使用陷阱: 2.7 和 8.1 / 3
// java默认浮点型常量 为 double
// 如声明 float型常量,需加 'f' 或 'F'
float num1 = 1.2 ;// 报错
float num2 = 1.2F;// ok
【案例】
// ------------------创建测试类------------------------------------
public class Test {
public static void main(String[] args) {
// 测试 double 和 float的不同
double num1 = 1.4;
float num2 = 2.8f;
System.out.println("double类型数num1= "+num1);
System.out.println("floatL类型数num2= "+num2);
//测试 浮点型的2种表示类型
double num3 = 1.234;
double num4 = 5.12E2; // 5.12*10^2 = 5.12*100 = 512.0
System.out.println("num3= "+num3);
System.out.println("num4= "+num4);
//浮点数使用的陷阱
double num5 = 2.7;
double num6 = 8.1 / 3; // 按道理 8.1 /3 = 2.7
System.out.println("num5= "+num5);
System.out.println("num6= "+num6);
//测试 num5和num6是否相等
if (num5 == num6){
System.out.println("num5 == num6 相等");
}else {
System.out.println("num5 == num6 不相等");
}
//如果要比较 两个运算后的 浮点型数是否相等
// 可以用差值绝对值的范围,表示精确度
// 因为有差异是一定的
if (Math.abs(num5 - num6)< 0.000001){
System.out.println("差值非常小,到规定范围,认为相等");
}
// 误差非常非常小
}
}
/*
-------------------运行结果-----------
double类型数num1= 1.4
floatL类型数num2= 2.8
num3= 1.234
num4= 512.0
num5= 2.7
num6= 2.6999999999999997
num5 == num6 不相等
差值非常小,到规定范围,认为相等
*/
按道理 8.1 / 3 = 2.7,但是num5 = 2.6999999999999997
说明,小数计算机中的储存是不精确
的
字符类型
声明
//格式
char 字符变量 = '字符';
//实例
char c = 'a';
【案例】
// ------------------创建测试类------------------------------------
public class Test {
public static void main(String[] args) {
char c1 = 'A';
char c2 = 97;
char c3 = '码';
// 输出
System.out.println("输入c1= "+c1);
System.out.println("输出c2= "+c2);
System.out.println("输出c3= "+c3);
System.out.println("将c1强转用(int)c1 转换为 = "+(int) c1);
System.out.println("将65强转用(char)65转换为 = "+(char) 65);
}
}
/*
-------------------运行结果-----------
输入c1= A
输出c2= a
输出c3= 码
将c1强转用(int)c1 转换为 = 65
将65强转用(char)65转换为 = A
*/
注意事项:
- char字符用
‘ ’
包裹起来,本质是 数字根据ASCII码的编码
详情: 字符本质和编码
布尔类型
自动类型转换
强制类型转换
常用编码
API文档
API (Application Program Interface,应用程序接口)
运算符
算术运算符
关系运算符
逻辑运算符
短路与
短路或
逻辑非
三元运算符
运算符优先级
标识符
关键字
键盘输入
控制语句
顺序
分支
条件
循环
String
String 代表字符串,Java中的字符串本质是字符数组
声明
语法
类型 [] 数组名;
类型[] 是 一组
[]: 表示一个数组
类型: 表示数组元素的类型
数组名: 即数组对象变量
,存放的是一个引用值
创建
使用 new
表示分配空间
【Demo-02】
// ------------------创建测试类------------------------------------
public class Test {
public static void main(String[] args) {
/*
创建数组方式 1: 声明同是创建
*/
// 创建元素个数为 5 的数组,元素类型为 int
int [] a = new int[5];
System.out.println("a= "+a);
System.out.println("a.length= "+a.length);
// 循环打印 a[0]~a[4]
for (int i=0 ;i<a.length;i++){
System.out.println("a"+"["+i+"]="+a[i]);
}
/*
创建数组方式 2: 先声明后创建
*/
// 声明数组变量 ,但是不创建
System.out.println("----------------------------------------------------");
int [] b;
// 分配空间
b = new int[5];
System.out.println("b= "+b);
for (int i=0 ;i<a.length;i++){
System.out.println("b"+"["+i+"]="+b[i]);
}
}
}
/*
-------------------运行结果-----------
a= [I@28d93b30
a.length= 5
a[0]=0
a[1]=0
a[2]=0
a[3]=0
a[4]=0
----------------------------------------------------
b= [I@1b6d3586
b[0]=0
b[1]=0
b[2]=0
b[3]=0
b[4]=0
*/
从上述测试可知:
- 数组分配空间有两种方式
- 分配但是没有赋值,
int
类型数组有默认值为0
- 数组对象 是一个
引用值
默认初值:
int,short,byte,long 默认值是
0
double,float 默认值是
0.0
char 默认值是
\u000
boolean 默认值是
false
String默认值是
null
赋值
第一次赋值叫做 初始化
方式:
- int [] a = new int[]{100,200,300}
动态初始化
- int [] b = {6,7,8,9}
静态初始化
【Demo-03】
// ------------------创建测试类------------------------------------
public class Test {
public static void main(String[] args) {
// 写法1: 分配空间同时赋值
int [] a = new int[]{100,200,300,400,500};
// 写法2: 省略 new int[] 效果一样
int [] b = {6,7,8,9};
System.out.println("数组a的a[1]= "+a[1]);
System.out.println("数组b的b[1]= "+b[1]);
}
}
/*
-------------------运行结果-----------
数组a的a[1]= 200
数组b的b[1]= 7
*/
为什么a[1]不是100,b[1]不是6呢?
这要讲到 数组下标的基0访问
什么是基0
?
- 西方人,把
星期一
当做这星期的第0天
,0
是最初的意思,把楼层的第一层
当做第0层
,编程思想和习惯源于西方 - 思想习惯源于文化,详情请看为什么英语first floor不是第一层?
英国
一楼:ground floor
直接与ground
接触的楼层叫一层。所以你在电梯里看到的G按钮,就是指的1层。
还有些酒店一般把这一层叫做lobby、ounge大堂、前厅是用来接待客人而不是用来居住的,而二层就理所当然的叫做first floor了!
二楼:first floor
并不是 second floor
三楼:second floor
顶层:the top floor
所以,所谓的基0
只是称呼不同而已,表达含义是一样的,也就是第二楼就是二楼那么高的位置,就是第二楼
所以
a[0]表示第一个元素,即100
,a[1]表示第二个元素,即200
…….
数组名[数字]
[ ]
里面的数字就是数组的下标,按照基0
规则访问数组元素
所以如果一个数组a有5
个元素,用下标访问第5个元素
的话应该用 a[4]
表示
访问
创建数组时 的 [数字]
中的数字
表示数组元素个数
int [] a = new int[5];
访问数组元素时,[数字]
中的数字
,表示按基0访问数组元素
,所以最大为 a[4]
a[4]
注意事项
如果使用 a[5]
去访问数组a,则会出现数组越界
现象
【Demo-04】: 测试数组越界
package com.martin.learn;
/**
* @author Martin
* @create $2021-02-17-20:26
**/
// ------------------创建测试类------------------------------------
public class Test {
public static void main(String[] args) {
// 定义有 5个元素的int类型数组 a
int [] a = new int[]{1,2,3,4,5};
System.out.println("a.length= "+a.length);
System.out.println("访问a[5]元素= "+a[5]);
System.out.println("访问a[4]元素= "+a[4]);
}
}
/*
-------------------运行结果-----------
a.length= 5
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
at com.martin.learn.Test.main(Test.java:15)
*/
Exception in thread "main" java.lang.ArrayIndexOutOfBoudsException: 5
表示 在 main中有异常 叫做 java.lang.ArrayIndexOutOfBoundsException:5
的异常,即 5 数组索引超出范围
数组长度
内存分析
数组本质是一个 引用类型变量指向一段连续的内存空间
数组的长度就是数组元素的个数
,用代码表示就是 数组名.length
增强型for循环
特性: 只能访问数组,不能修改数组
【案例】:使用增强型for循环遍历输出输入元素
package com.martin.learn;
/**
* @author Martin
* @create $2021-02-17-20:26
**/
// ------------------创建测试类------------------------------------
public class Test {
public static void main(String[] args) {
int [] arrays = {1,2,3,5,8,13,21,33,54};
//使用增强for循环遍历输出数组元素
for (int value:arrays) {
System.out.println("数组元素"+a);
}
}
}
/*
-------------------运行结果-----------
数组元素1
数组元素2
数组元素3
数组元素5
数组元素8
数组元素13
数组元素21
数组元素33
数组元素54
*/
语法
for(类型 数组元素:数组变量名){
//语句
}
表示从 数组变量名
的数组
中抽取每一个元素
【应用案例】: 求出数组int[] 最大值,{4,-1,9,10,23},并得到其下标
// ------------------创建测试类------------------------------------
public class Test {
public static void main(String[] args) {
//思路分析
/*
1、定义int[]数组 arr = {4,-1,9,10,23}
2、一开始不知道,假设max = arr[0],即arr[0]是最大值, maxIndex[0]就是最大值下标
3、从下标 1开始遍历数组,如果max < arr[1] ,意味着
arr[0]不是最大值,此时arr[1]是最大值,max = arr[当前下标],maxIndex = 当前下标
即 max = arr[1] , maxIndex = 1
4、当遍历完这个数组后,最后的 max = arr[当前下标], maxIndex[当前下标]
就是最大值下标,和最大值时的元素下标
*/
//------------------------------------
// 1、定义int[]数组 arr = {4,-1,9,10,23}
int[] arr = {4,-1,9,23};
// 2、一开始不知道,假设max = arr[0],即arr[0]是最大值, maxIndex[0]就是最大值下标
int max = arr[0];
int maxIndex = 0;
// 3、从下标 1开始遍历数组,如果max < arr[1] ,意味着
// arr[0]不是最大值,此时arr[1]是最大值,max = arr[当前下标],maxIndex = 当前下标
for (int i = 1;i<arr.length;i++){
if(max < arr[i]){
max = arr[i];
maxIndex = i;
}
}
// 4、当遍历完这个数组后,最后的 max = arr[当前下标], maxIndex[当前下标]
// 就是最大值,和最大值时的元素下标
System.out.println("最大值是: "+max+"\n最大值元素下标是: "+maxIndex);
}
}
/*
-------------------运行结果-----------
最大值是: 63
最大值元素下标是: 13
*/
数组赋值机制
【案例】: 测试数组赋值和基本类型赋值,指出值传递和引用传递不同
// ------------------创建测试类------------------------------------
public class Test {
public static void main(String[] args) {
// 基本类型赋值
int n1 = 10;
int n2 = n1;
n2 = 80;
System.out.println("n1= "+n1);
System.out.println("n2= "+n2);
// 数组赋值
int[] arr1 = {1,2,3};
int[] arr2 = arr1;
System.out.println("arr1[1] "+arr1[1]);
arr2[1] = 444;
System.out.println("arr2[1]= "+arr2[1]);
System.out.println("arr1[1]= "+arr1[1]);
}
}
/*
-------------------运行结果-----------
n1= 10
n2= 80
arr1[1] 2
arr2[1]= 444
arr1[1]= 444
*/
参考视频: 数组赋值机制,JVM内存分析
内存分析图:
数组操作
一、copyOf
语法:
Arrays.copyOf(数组,新数组的长度)
【案例】
package com.martin.learn;
import java.util.Arrays;
/**
* @author Martin
* @create $2021-02-17-20:26
**/
// ------------------创建测试类------------------------------------
public class Test {
public static void main(String[] args) {
int [] a ={1,2,3,4,5,6};
int [] b;
b = Arrays.copyOf(a,3);
System.out.println("数组a为: "+Arrays.toString(a));
System.out.println("数组b为: "+Arrays.toString(b));
}
}
/*
-------------------运行结果-----------
数组a为: [1, 2, 3, 4, 5, 6]
数组b为: [1, 2, 3]
*/
作用:
- 从
指定数组
的索引0
开始复制元素,直到元素个数为指定新数组的
个数,返回到新数组
如果新数组长度>
指定数组长度
意味着,新数组”从原数组长度
”位置往后,没有元素,默认值为 0
【案例】: 测试 copyOf,新数组长度大于(原)数组的长度的情况
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int [] a ={1,2,3,4,5,6};
int [] b;
b = Arrays.copyOf(a,10);
System.out.println("数组a为: "+Arrays.toString(a));
System.out.println("数组b为: "+Arrays.toString(b));
}
}
/*
-------------------运行结果-----------
数组a为: [1, 2, 3, 4, 5, 6]
数组b为: [1, 2, 3, 4, 5, 6, 0, 0, 0, 0]
*/
二、copyOfRange()
语法
public static double[] copyOfRange(double[] origianl,int from ,int to)
//表示将指定数组从索引 from到 to-1部分的元素复制到新的数组
【案例】
package com.martin.learn;
import java.util.Arrays;
/**
* @author Martin
* @create $2021-02-17-20:26
**/
// ------------------创建测试类------------------------------------
public class Test {
public static void main(String[] args) {
int [] a = {1,2,3,4,5,600,700,800};
int b [];
b = Arrays.copyOfRange(a,4,a.length);
System.out.println("数组a= "+Arrays.toString(a));
System.out.println("数组b= "+Arrays.toString(b));
}
}
/*
-------------------运行结果-----------
数组a= [1, 2, 3, 4, 5, 600, 700, 800]
数组b= [5, 600, 700, 800]
*/
作用:
- 表示复制
a数组
从索引4
位置元素(5)开始到索引a,length-1
位置即元素(800),返回到新的数组
三、toString()
语法:
Arrays.toString(指定数组对象);
【案例】
import java.util.Arrays;
// ------------------创建测试类------------------------------------
public class Test {
public static void main(String[] args) {
int [] a = {1,2,3,4,5,600,700,800};
System.out.println("数组对象a= "+a);
System.out.println("数组a元素= "+Arrays.toString(a));
}
}
/*
-------------------运行结果-----------
数组对象a= [I@28d93b30
数组a元素= [1, 2, 3, 4, 5, 600, 700, 800]
*/
作用:
- 遍历数组,输出数组格式字符串 ,
[ ]
包裹
总结:
- 数组对象变量是
引用类型
变量,数组是java中的储存数据的容器
- 数组访问最大下标为
数组对象.length
数组长度
表示数组中元素的个数
- 创建数组的步骤: ①声明数组变量,②开辟(分配)内存空间,③初始化
四、数组反转
要求: 将一个数组的元素反转,第一个元素在倒数第一个元素的位置,倒数第一个元素在第一个元素的位置,第二个元素在倒数第二个元素的位置,倒数第二个元素在第二个元素的位置……
int[] arr = {1,2,3,4,5,6};
反转后
arr = {6,5,4,3,2,1};
【案例】: 翻转数组
// ------------------创建测试类------------------------------------
public class Test {
public static void main(String[] args) {
/*
思路分析:
int[] arr = {1,2,3,4,5,6};
找规律
1、arr[0] 和 arr[5] 交换 arr = {6,2,3,4,5,1}
2、arr[1] 和 arr[4] 交换 arr = {6,5,3,4,2,1}
3、arr[2] 和 arr[3] 交换 arr = {6,5,4,3,2,1}
交换次数 = arr.length / 2
arr[0] 和 arr[5] ,1 + 5 = arr.length-1
arr[1] 和 arr[4] , 1 + 4 = arr.length-1
arr[2] 和 arr[3] , 1 + 4 = arr.length-1
*/
int[] arr = {1,2,3,4,5,6};
int temp = 0; // 创建临时变量保存值 ,优化在语句块外声明节约内存
int round = arr.length / 2; //定义 变量 round表示交换的次数,优化表达
System.out.println("交换前的数组: ");
for (int i = 0; i < arr.length; i++){
System.out.print(arr[i]);
}
//开始交换
for (int i = 0; i < round ; i++){ // 因为i从0开始,所以 i < round 表示的交换次数 是 round值
temp = arr[arr.length - 1 - i];
arr[arr.length - 1 -i] = arr[i]; //将数组前面的值 赋值 给 数组后面的位置
arr[i] = temp; // 将数组后面的值 赋值 给 数组前面位置
}
// 交换完毕
System.out.println("\n交换后的数组: ");
for (int i = 0; i < arr.length; i++){
System.out.print(arr[i]);
}
}
}
/*
-------------------运行结果-----------
交换前的数组:
123456
交换后的数组:
654321
*/
round = arr.length / 2 = 3
如果是 i < round
,则是 0,1,2 循环三次即交换三次,因此 i < round 的表达就是 交换的次数
五、数组扩容
要求: 实现动态给数组添加元素,实现对数组的扩容
基本思路:
基于原数组 创建 长度为 原数组长度 + 1
的新扩容的数组,给新数组添加元素
将新数组
的引用
传递 给 原数组,这样原数组
的元素就是新数组
的元素,达到扩容的效果
六、数组缩减
排序
冒泡排序
要求: 有五个无序
的数列,使用冒泡排序法
将其排列成 从小到大
的有序
序列
方法: 化繁为简,先死后活
分析过程图:
两数交换的逻辑图:
第一轮
// ------------------创建测试类------------------------------------
public class Test {
public static void main(String[] args) {
// 化繁为简,先死后活
// 方法 : 找规律
int[] arr = {24,69,80,57,13};
int temp = 0;// 用于辅助交换的变量
// 实现第一轮
// 第一轮,比较4次,循环4次
for (int j = 0; j < 4; j++){
// 如前面数 > 后面的数,则交换
if (arr[j]>arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
System.out.println("===第1轮排序后===");
for (int j = 0;j < arr.length; j++){
System.out.print(arr[j] + "\t");
}
}
}
/*
-------------------运行结果-----------
===第1轮排序后===
24 69 57 13 80
*/
后续三轮
// ------------------创建测试类------------------------------------
public class Test {
public static void main(String[] args) {
// 化繁为简,先死后活
// 方法 : 找规律
int[] arr = {24,69,80,57,13};
int temp = 0;// 用于辅助交换的变量
// 第一轮,比较4次,循环4次
for (int j = 0; j < 4; j++){
// 如前面数 > 后面的数,则交换
if (arr[j]>arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
System.out.println("===第1轮排序后===");
for (int j = 0;j < arr.length; j++){
System.out.print(arr[j] + "\t");
}
// 第2轮,比较3次,循环3次
for (int j = 0; j < 3; j++){
// 如前面数 > 后面的数,则交换
if (arr[j]>arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
System.out.println("\n===第2轮排序后===");
for (int j = 0;j < arr.length; j++){
System.out.print(arr[j] + "\t");
}
// 第3轮,比较2次,循环2次
for (int j = 0; j < 2; j++){
// 如前面数 > 后面的数,则交换
if (arr[j]>arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
System.out.println("\n===第3轮排序后===");
for (int j = 0;j < arr.length; j++){
System.out.print(arr[j] + "\t");
}
// 第4轮,比较1次,循环1次
for (int j = 0; j < 1; j++){
// 如前面数 > 后面的数,则交换
if (arr[j]>arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
System.out.println("\n===第4轮排序后===");
for (int j = 0;j < arr.length; j++){
System.out.print(arr[j] + "\t");
}
}
}
/*
-------------------运行结果-----------
===第1轮排序后===
24 69 57 13 80
===第2轮排序后===
24 57 13 69 80
===第3轮排序后===
24 13 57 69 80
===第4轮排序后===
13 24 57 69 80
*/
经过 观察,有4轮,且4轮的代码结构是一样的,这样可以用for循环 循环4轮,输出原来复杂代码
【综合代码】
第一轮 for循环控制 轮数
// ------------------创建测试类------------------------------------
public class Test {
public static void main(String[] args) {
// 化繁为简,先死后活
// 方法 : 找规律
int[] arr = {24,69,80,57,13};
int temp = 0;// 用于辅助交换的变量
int round = arr.length - 1; // 设置表示 轮 的变量,优化表达
//合并,整理
for(int i = 0; i < round; i++){ //循环,每一轮
for (int j = 0; j < round - i; j++){ //比较每一次
// 如前面数 > 后面的数,则交换
if (arr[j]>arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
System.out.println("\n===第"+(i+1)+"轮排序后===");
for (int j = 0;j < arr.length; j++){
System.out.print(arr[j] + "\t");
}
}
}
}
/*
-------------------运行结果-----------
===第1轮排序后===
24 69 57 13 80
===第2轮排序后===
24 57 13 69 80
===第3轮排序后===
24 13 57 69 80
===第4轮排序后===
13 24 57 69 80
*/
参考视频:冒泡排序
查找
顺序查找
顺序查找思想: 一个一个匹配
【案例】
有一字符串数组,有若干字符串元素,用户输入字符串,遍历数组,查找数列是否有其字符串
如有,则提示信息
import java.util.Scanner;
// ------------------创建测试类------------------------------------
public class Test {
public static void main(String[] args) {
/*
思路分析
1、定义字符串数组
2、接受用户输入字符串值,遍历数组,匹配值,如有,则提示出信息
没有则,也提示信息
*/
//定义字符串数组
String[] names = {"白眉鹰王","金毛狮王","紫衫龙王","青翼蝠王"};
Scanner myScanner = new Scanner(System.in);
//接受用户输入
System.out.println("请输入名字: ");
String findname = myScanner.next();
int index = -1; //默认是 -1
//遍历数组,逐一比较
for (int i = 0; i < names.length; i++){
// 比较字符串 equals
if(findname.equals(names[i])){
System.out.println("恭喜找到"+findname);
System.out.println("下标为: "+i);
// 设置状态变量
index = i; //状态变量改变,表示找到
break; //退出
}
}
if (index == -1){
System.out.println("没有找到"+findname);
}
}
}
/*
-------------------运行结果-----------
金毛狮王
恭喜找到金毛狮王
下标为: 1
*/