Java基础1(数组)
一、Java语言概述
Java软件开发介绍
常用DOS命令
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8apwxCoX-1635843764665)(Java.assets/image-20210517210042760.png)]
cd -change directory
rd -remove directory
del -delete
dir -directory
md -make directory
c盘进入D盘 d:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s4A4fARY-1635843764670)(Java.assets/image-20210518211629029.png)]
常用指令 https://baike.baidu.com/item/dos/6672671?fr=aladdin
Java语言概述
Java技术体系平台
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jclzfCEG-1635843764672)(Java.assets/image-20210519101752558.png)]
Java在各领域的应用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NMLaR9fA-1635843764674)(Java.assets/image-20210519101825085.png)]
Java语言运行机制及运行过程
Java语言的特点
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vjITkzKr-1635843764676)(Java.assets/image-20210517180949548.png)]
Java两种核心机制
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hxVJZIsD-1635843764676)(Java.assets/image-20210517181250101.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5gXcJWlr-1635843764677)(Java.assets/image-20210517181327772.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-85Vtnmtz-1635843764678)(Java.assets/image-20210517181355530.png)]
java语言的环境搭建
JDK、JRE、JVM 的关系
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2wx2CvP4-1635843764679)(Java.assets/image-20210514204141099.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3Ln6mn1x-1635843764680)(Java.assets/image-20210517182146826.png)]
Java语言环境的搭建
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vMqo1pgb-1635843764681)(Java.assets/image-20210517211554351.png)]
开发体验-HelloWorld
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IrzdU3a5-1635843764682)(Java.assets/image-20210518110253454.png)]
如
javac FamilyAccount.java // 此时不区分大小写
java FamilyAccount // 此时区分大小写
关于Java里边文件名大小写
字节码名=类名,字节码文件对应类,函数里边有几个类就会生成几个字节码文件。
windows系统不区分大小写
Java代码严格区分大小写
故javac编译的时候 搜索文件夹里边文件名的时候不区分大小写,但用java运行class文件的时候要区分大小写。
注释
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6rTtFzkz-1635843764683)(Java.assets/image-20210518163819864.png)]
Java API文档
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZLsALx6q-1635843764684)(Java.assets/image-20210518170854650.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2jeNaMMb-1635843764685)(Java.assets/image-20210519114841412.png)]
二、Java基本语法
关键字和保留字
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nU6PjIwd-1635843764686)(Java.assets/image-20210520092714695.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fwADwmbx-1635843764687)(Java.assets/image-20210520092732155.png)]
标识符(可以自己取名字的)
规则
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d8stIeJS-1635843764688)(Java.assets/image-20210519151102722.png)]
规范
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tdBEcLAd-1635843764689)(Java.assets/image-20210519151128836.png)]
两个简单的输出语句
1. 参数有区别:
System.out.println() 可以不写参数
System.out.print(参数) 参数不能为空.必须有
2.效果有区别
println :会在输出完信息后进行换行,产生一个新行
print: 不会产生新行
3.println更简洁, print更灵活
print可以后面跟"\n"来达到和println一样的效果
也可以跟"\t" 制表符, 等.
————————————————
原文链接:https://blog.csdn.net/weixin_44720673/article/details/88791884
变量
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-APbPo8VU-1635843764689)(Java.assets/image-20210519165140783.png)]
布尔类型
Java中的真,假只能由布尔型(boolean)的true和false来表示,不对应任何数值.
基本数据类型转换
自动类型转换
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-132HR5wv-1635843764690)(Java.assets/image-20210819163210265.png)]
Java里边整型常量默认为int型,浮点型常量默认为
强制类型转换
变量运算规则的两种特殊情况
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q6HJP7qZ-1635843764691)(Java.assets/image-20210519180217183.png)]
数据123213后不加L时,默认是int型再转换成long型。这种情况下,过大的整数会出现编译失败。
进制
见ppt
运算符
算术运算符
自增自减运算符
short s1 = 10;
//s1 = s1 + 1;//编译失败 常量默认是int型,s1运算时候会自动转换为int型
//s1 = (short)(s1 + 1);//正确的
s1++;//自增1不会改变本身变量的数据类型
System.out.println(s1);
//问题:
byte bb1 =127;
bb1++;
System.out.println("bb1 = " + bb1);
结果: bb1 = -128
//练习1
int i = 1;
i *= 0.1;
System.out.println(i);//0
i++;
System.out.println(i);//1
连接符 ( + )
赋值运算符
short s1 = 10;
//s1 = s1 + 2;//编译失败 常量默认是int型,s1运算时候会自动转换为int型
s1 += 2;//结论:不会改变变量本身的数据类型
System.out.println(s1);
tips
//开发中,如果希望变量实现+2的操作,有几种方法?(前提:int num = 10;)
//方式一:num = num + 2;
//方式二:num += 2; (推荐) 不会改变本身数据类型
//开发中,如果希望变量实现+1的操作,有几种方法?(前提:int num = 10;)
//方式一:num = num + 1;
//方式二:num += 1;
//方式三:num++; (推荐)
逻辑运算符
//说明:
//1.逻辑运算符操作的都是boolean类型的变量
//区分& 与 &&
//相同点1:& 与 && 的运算结果相同
//相同点2:当符号左边是true时,二者都会执行符号右边的运算
//不同点:当符号左边是false时,&继续执行符号右边的运算。&&不再执行符号右边的运算。
//开发中,推荐使用&&
boolean b1 = true;
b1 = false;
int num1 = 10;
if(b1 & (num1++ > 0)){
System.out.println("我现在在北京");
}else{
System.out.println("我现在在南京");
}
System.out.println("num1 = " + num1);
boolean b2 = true;
b2 = false;
int num2 = 10;
if(b2 && (num2++ > 0)){
System.out.println("我现在在北京");
}else{
System.out.println("我现在在南京");
}
System.out.println("num2 = " + num2);
// 区分:| 与 ||
//相同点1:| 与 || 的运算结果相同
//相同点2:当符号左边是false时,二者都会执行符号右边的运算
//不同点3:当符号左边是true时,|继续执行符号右边的运算,而||不再执行符号右边的运算
//开发中,推荐使用||
位运算符
//练习:交换两个变量的值
int num1 = 10;
int num2 = 20;
System.out.println("num1 = " + num1 + ",num2 = " + num2);
//方式一:定义临时变量的方式
//推荐的方式
int temp = num1;
num1 = num2;
num2 = temp;
//方式二:好处:不用定义临时变量
//弊端:① 相加操作可能超出存储范围 ② 有局限性:只能适用于数值类型
//num1 = num1 + num2;
//num2 = num1 - num2;
//num1 = num1 - num2;
//方式三:使用位运算符
//有局限性:只能适用于数值类型
//num1 = num1 ^ num2;
//num2 = num1 ^ num2;
//num1 = num1 ^ num2;
System.out.println("num1 = " + num1 + ",num2 = " + num2);
三元运算符
三元运算符和if-else的使用说明
/*
运算符之六:三元运算符
1.结构:(条件表达式)? 表达式1 : 表达式2
2. 说明
① 条件表达式的结果为boolean类型
② 根据条件表达式真或假,决定执行表达式1,还是表达式2.
如果表达式为true,则执行表达式1。
如果表达式为false,则执行表达式2。
③ 表达式1 和表达式2要求是一致的。
④ 三元运算符可以嵌套使用
3.
凡是可以使用三元运算符的地方,都可以改写为if-else
反之,不成立。
4. 如果程序既可以使用三元运算符,又可以使用if-else结构,那么优先选择三元运算符。原因:简洁、执行效率高。
*/
程序流程控制
顺序结构
分支结构
if-else
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2OTDcVor-1635843764692)(Java.assets/image-20210524111456158.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R0P84BWg-1635843764693)(Java.assets/image-20210524111511217.png)]
Scanner类语法 (键盘输入)
/*
如何从键盘获取不同类型的变量:需要使用Scanner类
具体实现步骤:
1.导包:import java.util.Scanner;
2.Scanner的实例化:Scanner scan = new Scanner(System.in);
3.调用Scanner类的相关方法(next() / nextXxx()),来获取指定类型的变量
注意:
需要根据相应的方法,来输入指定类型的值。如果输入的数据类型与要求的类型不匹配时,会报异常:InputMisMatchException
导致程序终止。
*/
//1.导包:import java.util.Scanner;
import java.util.Scanner;
class ScannerTest{
public static void main(String[] args){
//2.Scanner的实例化
Scanner scan = new Scanner(System.in);
//3.调用Scanner类的相关方法
System.out.println("请输入你的姓名:");
String name = scan.next(); //读取字符串
System.out.println(name);
System.out.println("请输入你的芳龄:");
int age = scan.nextInt(); //读取数字
System.out.println(age);
}
}
math类(随机数的产生)
//课后练习4:如何获取一个随机数:10 - 99
int value = (int)(Math.random() * 90 + 10);
// [0.0,1.0) --> [0.0,90.0) --->[10.0, 100.0) -->[10,99]
System.out.println(value);
//Math.random() : [0.0,1.0)
//公式:获取[a,b]范围内的随机数:
//(int)(Math.random() * (b - a + 1) + a)
switch-case
/*
分支结构之二:switch-case
1.格式
switch(表达式){
case 常量1:
执行语句1;
//break;
case 常量2:
执行语句2;
//break;
...
default:
执行语句n;
//break;
}
2.说明:
① 根据switch表达式中的值,依次匹配各个case中的常量。一旦匹配成功,则进入相应case结构中,调用其执行语句。
当调用完执行语句以后,则仍然继续向下执行其他case结构中的执行语句,直到遇到break关键字或此switch-case结构
末尾结束为止。
② break,可以使用在switch-case结构中,表示一旦执行到此关键字,就跳出switch-case结构
③ switch结构中的表达式,只能是如下的6种数据类型之一:
byte 、short、char、int、枚举类型(JDK5.0新增)、String类型(JDK7.0新增)
④ case 之后只能声明常量。不能声明范围。
⑤ break关键字是可选的。
⑥ default:相当于if-else结构中的else.
default结构是可选的,而且位置是灵活的。
*/
if-else和switch-case的使用说明
/*说明:
1. 凡是可以使用switch-case的结构,都可以转换为if-else。反之,不成立。
2. 我们写分支结构时,当发现既可以使用switch-case,(同时,switch中表达式的取值情况不太多),
又可以使用if-else时,我们优先选择使用switch-case。原因:switch-case执行效率稍高。
*/
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YYT8x7P7-1635843764694)(Java.assets/image-20210524152746523.png)]
两边执行效率稍高一些
循环结构
For循环
关于变量未赋值导致编译不过的一个问题
class ReviewTest{
public static void main(String[] args){
int sum ; //此处未赋值会导致编译过不了,因为编译器会判定For循环不一定能进入,sum不一定会被赋值。
//若去掉For循环,只留下if-elss可以通过编译。 p
for(int i = 1;i <= 100;i++){
if(4 % 2 == 0){
System.out.println(i);
sum = 1;
}else{
sum = 2;
}
}
System.out.println(sum);
}
}
while循环
do-while循环
嵌套循环
九九乘法表
10000以内所有质数
//10000以内的质数(素数)
class PrimeNumberTest {
public static void main(String[] args) {
int flag = 0;
int count = 0;//记录质数的个数。
long start = System.currentTimeMillis();
for(int i = 2;i <= 100000;i++){
//优化二:对本身质数的自然数的优化。
for(int j = 2;j <= Math.sqrt(i);j++){
if(i % j == 0 && i != j){
flag = 1;
break;//优化一: 只对本身非质数的自然数的优化。
}
}
if(flag == 0)
//System.out.println(i);
count++;
flag = 0;// 重置flag
}
long end = System.currentTimeMillis();
System.out.println("个数为:" + count);
System.out.println("所花费的时间为:" + (end - start)); // 19825 - 2542
}
}
break和continue和return关键字
1、基本功能
/*
break和continue关键字的使用
使用范围 循环中使用的作用(不同点) 相同点
break: switch-case
循环结构中 结束当前循环 关键字后面不能声明执行语句
continue: 循环结构中 结束当次循环 关键字后面不能声明执行语句
(之后执行i++)
*/
2、带标签的break和continue
class BreakContinueTest {
public static void main(String[] args) {
for(int i = 1;i <= 10;i++){
if(i % 4 == 0){
break;//输出123
//continue;//输出123567910
//System.out.println("今晚迪丽热巴要约我!!!");
}
System.out.print(i);
}
System.out.println("\n");
//******************************
label:for(int i = 1;i <= 4;i++){
for(int j = 1;j <= 10;j++){
if(j % 4 == 0){
//break;//默认跳出包裹此关键字最近的一层循环。
//continue; //结束包裹此关键字最近的当次循环
//break label;//结束指定标识的一层循环结构
continue label;//结束指定标识的一层循环结构当次循环
}
System.out.print(j);
}
System.out.println();
}
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-htrBe0hs-1635843764695)(Java.assets/image-20210818170811746.png)]
Eclipse的安装与配置
Eclipse的使用配置.pdf
数组
重点掌握一维数组、二维数组的六个基本点。
数组的概述
/*
* 一、数组的概述
* 1.数组的理解:数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,
* 并通过编号的方式对这些数据进行统一管理。
*
* 2.数组相关的概念:
* >数组名
* >元素
* >角标、下标、索引
* >数组的长度:元素的个数
*
* 3.数组的特点:
* 1)数组是有序排列的
* 2)数组属于引用数据类型的变量。数组的元素,既可以是基本数据类型,也可以是引用数据类型
* 3)创建数组对象会在内存中开辟一整块连续的空间
* 4)数组的长度一旦确定,就不能修改。
*
* 4. 数组的分类:
* ① 按照维数:一维数组、二维数组、。。。
* ② 按照数组元素的类型:基本数据类型元素的数组、引用数据类型元素的数组
*
* 5. 一维数组的使用
* ① 一维数组的声明和初始化
* ② 如何调用数组的指定位置的元素
* ③ 如何获取数组的长度
* ④ 如何遍历数组
* ⑤ 数组元素的默认初始化值 :见ArrayTest1.java
* ⑥ 数组的内存解析 :见ArrayTest1.java
*/
数组的使用
一维数组
1、一维数组的使用
/* 5. 一维数组的使用
* ① 一维数组的声明和初始化
* ② 如何调用数组的指定位置的元素
* ③ 如何获取数组的长度
* ④ 如何遍历数组
* ⑤ 数组元素的默认初始化值 :见ArrayTest1.java
* ⑥ 数组的内存解析 :见ArrayTest1.java
*/
ArrayTest.java
package com.atguigu.java;
public class ArrayTest {
public static void main(String[] args) {
//1. 一维数组的声明和初始化
int num;//声明
num = 10;//初始化
int id = 1001;//声明 + 初始化
int[] ids;//声明
//1.1 静态初始化:数组的初始化和数组元素的赋值操作同时进行
ids = new int[]{1001,1002,1003,1004};
//1.2动态初始化:数组的初始化和数组元素的赋值操作分开进行
String[] names = new String[5];
//Sum: 前边都是空的,后边指定长度或者元素。
//错误的写法:
// int[] arr1 = new int[];既没有赋值也没有指定长度
// int[5] arr2 = new int[5];前边中括号永远是空的
// int[] arr3 = new int[3]{1,2,3}; 静态和动态合在一块儿了
//也是正确的写法:
int[] arr4 = {1,2,3,4,5};//类型推断
//Sum总结:数组一旦初始化完成,其长度就确定了。
//2.如何调用数组的指定位置的元素:通过角标的方式调用。
//数组的角标(或索引)从0开始的,到数组的长度-1结束。
names[0] = "王铭";
names[1] = "王赫";
names[2] = "张学良";
names[3] = "孙居龙";
names[4] = "王宏志";//charAt(0)
// names[5] = "周扬"; 数组越界
//3.如何获取数组的长度。
//属性:length
System.out.println(names.length);//5
System.out.println(ids.length);、//4
//4.如何遍历数组
/*System.out.println(names[0]);
System.out.println(names[1]);
System.out.println(names[2]);
System.out.println(names[3]);
System.out.println(names[4]);*/
for(int i = 0;i < names.length;i++){
System.out.println(names[i]);
}
}
}
1、类型推断:数组的静态初始化和数组元素的赋值操作同时进行时。动态初始化时不能省。
一维数组: int[] arr4 =new int[ ]{1,2,3,4,5};
可以写成 int[] arr4 = {1,2,3,4,5};
二维数组:int[] arr5 [] = new int[ ] [ ]{{1,2,3},{4,5},{6,7,8}};
可以写成 int[] arr5[] = {{1,2,3},{4,5},{6,7,8}};
2、中括号和变量名的位置不分前后。数据类型永远在最前边。
一维数组:可以写int[ ] arr4 或者int arr4[] 。一般采用前者。
二维数组:int[][] [ ] [ ]arr 可以写成int[] arr[]或者 int arr5[ ] [ ]
3、数组一旦初始化完成,其长度就确定了。将静态和动态杂糅在一起也是错的。
[][]
ArrayTest1.java
package com.atguigu.java;
/*
* ⑤ 数组元素的默认初始化值
* > 数组元素是整型:0
* > 数组元素是浮点型:0.0
* > 数组元素是char型:0或'\u0000',而非'0'
* > 数组元素是boolean型:false
*
* > 数组元素是引用数据类型:null
*
* ⑥ 数组的内存解析
*/
public class ArrayTest1 {
public static void main(String[] args) {
//5.数组元素的默认初始化值
int[] arr = new int[4];
for(int i = 0;i < arr.length;i++){
System.out.println(arr[i]);
}
System.out.println("**********");
short[] arr1 = new short[4];
for(int i = 0;i < arr1.length;i++){
System.out.println(arr1[i]);
}
System.out.println("**********");
float[] arr2 = new float[5];
for(int i = 0;i < arr2.length;i++){
System.out.println(arr2[i]);
}
System.out.println("**********");
char[] arr3 = new char[4];
for(int i = 0;i < arr3.length;i++){
System.out.println("----" + arr3[i] + "****");
}
if(arr3[0] == 0){
System.out.println("你好!");
}
System.out.println("**********");
boolean[] arr4 = new boolean[5];
System.out.println(arr4[0]);
System.out.println("**********");
String[] arr5 = new String[5];
System.out.println(arr5[0]);
if(arr5[0] == null){
System.out.println("北京天气不错!");
}
}
}
2、一维数组的内存简化结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JZpw0OOf-1635843764696)(Java.assets/image-20211025212600270.png)]
1、栈(stack)中保存局部变量,方法中定义的变量都是局部变量。(比如main方法)
2、堆(heap)中一般保存new出来的变量,如数组、对象
3、字符串常量池一般保存string类
4、静态域存放static类
一维数组的内存解析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m0fAppDD-1635843764697)(Java.assets/image-20211025214156768.png)]
1、堆中new出来的数据一开始都有默认值,之后对其进行初始化。
2、变量arr1被指定到堆中新的结构之后,arr1变量之前保存的地址值所在的结构会在某一时间被系统回收。(垃圾回收机制)
3、执行完main方法之后,main方法中定义的所有变量都出栈释放,这些变量所指向的结构所占用的内存也将被系统回收。
3、一维数组练习
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k0kF2HGQ-1635843764698)(Java.assets/image-20211026183603658.png)]
/*
1、快速导包:点击Scanner类名处的错误提示或者 快捷键 ctrl+shift+o
2、alt+up/down 代码上下移动
3、ctrl+shift+f 调整代码格式
4、ctrl+i 调整代码缩进
5、alt+/ 智能补全
6、ctrl+1 智能补全
7、ctrl+shift+r批量修改同名变量名
*/
/*
* 2. 从键盘读入学生成绩,找出最高分,并输出学生成绩等级。
成绩>=最高分-10 等级为’A’
成绩>=最高分-20 等级为’B’
成绩>=最高分-30 等级为’C’
其余 等级为’D’
提示:先读入学生人数,根据人数创建int数组,存放学生成绩。
*
*/
package com.atguigu.exer;
import java.util.Scanner;
public class ArrayDemo1 {
public static void main(String[] args) {
//1.使用Scanner,读取学生个数
Scanner scanner = new Scanner(System.in);
System.out.println("请输入学生人数:");
int number = scanner.nextInt();
//2.创建数组,存储学生成绩:动态初始化
int[] scores = new int[number];
//3.给数组中的元素赋值
System.out.println("请输入" + number + "个学生成绩:");
int maxScore = 0;
for(int i = 0;i < scores.length;i++){
scores[i] = scanner.nextInt();
//4.获取数组中的元素的最大值:最高分
if(maxScore < scores[i]){
maxScore = scores[i];
}
}
// for(int i = 0;i < scores.length;i++){
// if(maxScore < scores[i]){
// maxScore = scores[i];
// }
// }
//5.根据每个学生成绩与最高分的差值,得到每个学生的等级,并输出等级和成绩
char level;
for(int i = 0;i < scores.length;i++){
if(maxScore - scores[i] <= 10){
level = 'A';
}else if(maxScore - scores[i] <= 20){
level = 'B';
}else if(maxScore - scores[i] <= 30){
level = 'C';
}else{
level = 'D';
}
System.out.println("student " + i +
" score is " + scores[i] + ",grade is " + level);
}
}
}
二维数组
1、二维数组的使用part1
/*
* 二维数组的使用
*
* 1.理解:
* 对于二维数组的理解,我们可以看成是一维数组array1又作为另一个一维数组array2的元素而存在。
* 其实,从数组底层的运行机制来看,其实没有多维数组。
*
* 2. 二维数组的使用:
* ① 二维数组的声明和初始化
* ② 如何调用数组的指定位置的元素
* ③ 如何获取数组的长度
* ④ 如何遍历数组
* ⑤ 数组元素的默认初始化值 :见 ArrayTest3.java
* ⑥ 数组的内存解析 :见 ArrayTest3.java
*
*
*/
ArrayTest2.java
package com.atguigu.java;
public class ArrayTest2 {
public static void main(String[] args) {
//1.二维数组的声明和初始化
int[] arr = new int[]{1,2,3};//一维数组
//静态初始化
int[][] arr1 = new int[][]{{1,2,3},{4,5,6},{6,7,8}};
//动态初始化1
String[][] arr2 = new String[3][2];
//动态初始化2
String[][] arr3 = new String[3][];
//错误的情况
// String[][] arr4 = new String[][4]; 第一维的数字不能为空
// String[4][3] arr5 = new String[][];前边括号必须为空
// int[][] arr6 = new int[4][3]{{1,2,3},{4,5},{6,7,8}};
//长度和赋值只能存在一个,不能同时存在
//也是正确的写法:
int[] arr4[] = new int[][]{{1,2,3},{4,5,9,10},{6,7,8}};
int[] arr5[] = {{1,2,3},{4,5},{6,7,8}}; //类型推断
//2.如何调用数组的指定位置的元素
System.out.println(arr1[0][1]);//2
System.out.println(arr2[1][1]);//null
arr3[1] = new String[4];
System.out.println(arr3[1][0]);
//3.获取数组的长度
System.out.println(arr4.length);//3
System.out.println(arr4[0].length);//3
System.out.println(arr4[1].length);//4
//4.如何遍历二维数组
for(int i = 0;i < arr4.length;i++){
for(int j = 0;j < arr4[i].length;j++){
System.out.print(arr4[i][j] + " ");
}
System.out.println();
}
}
}
1、二维数组动态初始化时,第二维的数字可以留空。
2、二维数组的使用part2
/*
* 二维数组的使用:
* 规定:二维数组分为外层数组的元素,内层数组的元素
* int[][] arr = new int[4][3];
* 外层元素:arr[0],arr[1]等
* 内层元素:arr[0][0],arr[1][2]等
*
* ⑤ 数组元素的默认初始化值
* 针对于初始化方式一:比如:int[][] arr = new int[4][3];
* 外层元素的初始化值为:地址值
* 内层元素的初始化值为:与一维数组初始化情况相同
*
* 针对于初始化方式二:比如:int[][] arr = new int[4][];
* 外层元素的初始化值为:null
* 内层元素的初始化值为:不能调用,否则报错。
*
* ⑥ 数组的内存解析
*
*/
ArrayTest3.java
package com.atguigu.java;
public class ArrayTest3 {
public static void main(String[] args) {
int[][] arr = new int[4][3];
System.out.println(arr[0]);//[I@15db9742 是一个一维地址值
System.out.println(arr[0][0]);//0
// System.out.println(arr);//[[I@6d06d69c 是一个二维地址值
System.out.println("*****************");
float[][] arr1 = new float[4][3];
System.out.println(arr1[0]);//地址值
System.out.println(arr1[0][0]);//0.0
System.out.println("*****************");
String[][] arr2 = new String[4][2];
System.out.println(arr2[1]);//地址值
System.out.println(arr2[1][1]);//null
System.out.println("*****************");
double[][] arr3 = new double[4][];
System.out.println(arr3[1]);//null
// System.out.println(arr3[1][0]);//报错
}
}
3、二维数组的内存解析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5oWb5VtV-1635843764699)(Java.assets/image-20211026123617260.png)]
1、数组也属于引用类型,引用类型的变量只有两种值,null 或者 地址值。
4、二维数组练习
Exer1
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fIWN7Pi7-1635843764700)(Java.assets/image-20211027104323307.png)]
//1、老师的答案,静态数组
//2、自己写的,动态数组
//此处静态数组更好,因为二维的数量不是固定的
package com.atguigu.exer;
public class ArrayExer1 {
public static void main(String[] args) {
int[][] arr = new int[][]{{3,5,8},{12,9},{7,0,6,4}};
int sum = 0;//记录总和
for(int i = 0;i < arr.length;i++){
for(int j = 0;j < arr[i].length;j++){
sum += arr[i][j];
}
}
System.out.println("总和为:" + sum);
}
}
//----------------------------------------------------------------
package com.atguigu.exer;
import java.util.Scanner;
public class ArrayExer1 {
public static void main(String[] args) {
//1、定义一个sum变量来存储元素的和
int sum = 0;
//2、创建动态数组,在输入数组数值的同时对sum进行累加
//此处用静态初始化更好,因为二维的个数不是全都一样的
int[][] arr = new int[3][4];
Scanner scan = new Scanner(System.in);
for(int i = 0;i < arr.length;i++){
for(int j = 0;j < arr[i].length;j++){
arr[i][j] = scan.nextInt();
sum += arr[i][j];
}
}
System.out.println(sum);
}
}
Exer2
声明:int[] x,y[]; 在给x,y变量赋值以后,以下选项允许通过编译的是:
//此处x是一维数组,y是二维数组
x[0] = y; //no; 元素≠二维地址值
y[0] = x; //yes;
y[0][0] = x; //no;元素≠一维地址值
x[0][0] = y; //no;前边不存在
y[0][0] = x[0]; //yes
x = y; //no;一维地址值≠二维地址值
提示:
一维数组:int[] x 或者int x[]
二维数组:int[][] y 或者 int[] y[] 或者 int y[][]
1、一维数组名和二维数组名之间也不能相互赋值。二维不能赋值给一维,虽然都是地址值,但地址值前还有变量的类型。如二维地址打印出来前边还会显示"[["
2、可以赋值的两种情况,类型一样或者可以自动类型提升。
Exer3
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tZOwf1qa-1635843764701)(Java.assets/image-20211027111036224.png)]
其实就是(a+b)n 开出来次方之后的系数值。
//前老师后自己
//1.学会写注释的格式,要有层次感,看起来更清晰直观
//2.本质就是初始化二维数组,并按照特定要求赋值
package com.atguigu.exer;
public class YangHuiTest {
public static void main(String[] args) {
//1.声明并初始化二维数组
int[][] yangHui = new int[10][];
//2.给数组的元素赋值
for(int i = 0;i < yangHui.length;i++){
yangHui[i] = new int[i + 1];
//2.1 给首末元素赋值
yangHui[i][0] = yangHui[i][i] = 1;//连续赋值
//2.2 给每行的非首末元素赋值
//if(i > 1){
for(int j = 1;j < yangHui[i].length - 1;j++){
yangHui[i][j] = yangHui[i-1][j-1] + yangHui[i-1][j];
}
//}
}
//3.遍历二维数组
for(int i = 0;i < yangHui.length;i++){
for(int j = 0;j < yangHui[i].length;j++){
System.out.print(yangHui[i][j] + " ");
}
System.out.println();
}
}
}
//-------------------------------------------------------------
package com.atguigu.exer;
public class YangHuiTest {
public static void main(String[] args) {
//1.先动态初试化一个二维数组,一维定10二维不定。二维的维数放到循环中确定
int[][] yanghui = new int[10][]; //一共有10行
//2.用一个for循环去填值,用if去判断是否是最前边或者最后边一列,分别按照规则填值。
for(int i = 0;i < 10;i++){
yanghui[i] = new int[i+1]; //第0行也有1个元素,第n行有n+1个元素
for(int j = 0;j < yanghui[i].length;j++){
//2.1给首末元素赋值
if(j == 0 || j == yanghui[i].length - 1){
//每一行的第一个元素和最后一个元素都是 1
yanghui[i][j] = 1;
//2.2 给每行的非首末元素赋值
}else{
yanghui[i][j] = yanghui[i-1][j-1] + yanghui[i-1][j];
}
//3.输出
System.out.print(yanghui[i][j] + " ");
}
//每一行打印一个换行
System.out.println();
}
}
}
Tips
1、main方法中的变量都是局部变量,储存在栈里边。
局部变量:声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量
2、引用类型的变量只有两种值,null 或者 地址值。
3、一维数组名和二维数组名之间也不能相互赋值。二维不能赋值给一维,虽然都是地址值,但地址值前还有变量的类型。如二维地址打印出来前边还会显示"[["
数组的常用算法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-41HCiyUG-1635843764702)(Java.assets/image-20211027150618949.png)]
数组元素的赋值
1、杨辉三角(见上)
2、回形数
求数值型数组中元素的max、min、ave、sum等
1、Math.random()函数返回一个在[0.0,1)之间的double类型的值。
公式:
获取[a,b]范围内的随机数: (int)(Math.random() * (b - a + 1) + a)
package com.atguigu.java;
/*
* 算法的考查:求数值型数组中元素的最大值、最小值、平均数、总和等
*
* 定义一个int型的一维数组,包含10个元素,分别赋一些随机整数,
* 然后求出所有元素的最大值,最小值,和值,平均值,并输出出来。
* 要求:所有随机数都是两位数。
*
* [10,99]
* 公式:(int)(Math.random() * (99 - 10 + 1) + 10)
* [0,1) * 90 >> [0,90) + 10 >> [10,100) >> [10,99]
*/
public class ArrayTest1 {
public static void main(String[] args) {
int[] arr = new int[10];
for(int i = 0;i < arr.length;i++){
arr[i] = (int)(Math.random() * (99 - 10 + 1) + 10);
}
//遍历
for(int i = 0;i < arr.length;i++){
System.out.print(arr[i] + "\t");
}
System.out.println();
//求数组元素的最大值
int maxValue = arr[0];
for(int i = 1;i < arr.length;i++){
if(maxValue < arr[i]){
maxValue = arr[i];
}
}
System.out.println("最大值为:" + maxValue);
//求数组元素的最小值
int minValue = arr[0];
for(int i = 1;i < arr.length;i++){
if(minValue > arr[i]){
minValue = arr[i];
}
}
System.out.println("最小值为:" + minValue);
//求数组元素的总和
int sum = 0;
for(int i = 0;i < arr.length;i++){
sum += arr[i];
}
System.out.println("总和为:" + sum);
//求数组元素的平均数
int avgValue = sum / arr.length;
System.out.println("平均数为:" + avgValue);
}
}
//---------------------------------------------------------
pa` ckage com.atguigu.java;
public class ArrayTest1 {
public static void main(String[] args) {
//初始化数组并用循环对其赋值赋值
int[] arr = new int[10];
int sum,min,max,ave;
sum = ave = 0;
min = 99;
max = 10;
for(int i = 0;i < arr.length;i++){
arr[i] = (int)(Math.random()*90 + 10);
//计算和值
sum += arr[i];
//找出最值
if(max < arr[i]){
max = arr[i];
}
if(min > arr[i]){
min = arr[i];
}
}
//平均值
ave = sum / arr.length;
System.out.println("最大值为:" + max);
System.out.println("最小值为:" + min);
System.out.println("和值为:" + sum);
System.out.println("平均值为:" + ave);
}
}
数组的复制、反转、查找(线性查找、二分法查找)
1、分清楚复制和赋值
赋值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0zGRY1l3-1635843764703)(Java.assets/image-20211027174803482.png)]
复制
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ThYCdVud-1635843764704)(Java.assets/image-20211027174846515.png)]
package com.atguigu.exer;
/*
* 使用简单数组
(1)创建一个名为ArrayExer2的类,在main()方法中声明array1和array2两个变量,他们是int[]类型的数组。
(2)使用大括号{},把array1初始化为8个素数:2,3,5,7,11,13,17,19。
(3)显示array1的内容。
(4)赋值array2变量等于array1,修改array2中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2)。打印出array1。
*
* 思考:array1和array2是什么关系?array1和array2地址值相同,都指向了堆空间的唯一的一个数组实体。
* 拓展:修改题目,实现array2对array1数组的复制
*/
public class ArrayExer2 {
public static void main(String[] args) { //alt + /
int[] array1,array2;
array1 = new int[]{2,3,5,7,11,13,17,19};
//显示array1的内容
for(int i = 0;i < array1.length;i++){
System.out.print(array1[i] + "\t");
}
//赋值 array2变量等于array1
//不能称作数组的复制。
array2 = array1;
//----------------------------------------------
//数组的复制:
array3 = new int[array1.length];
for(int i = 0;i < array3.length;i++){
array3[i] = array1[i];
}
//----------------------------------------------
//修改array2中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2)
for(int i = 0;i < array2.length;i++){
if(i % 2 == 0){
array2[i] = i;
}
}
System.out.println();
//打印出array1
for(int i = 0;i < array1.length;i++){
System.out.print(array1[i] + "\t");
}
}
}
2、查找
1、字符串是否相等用 dest.equals() line50
2、判断是什么条件结束的循环,用flag标记一下
3、二分法查找前提,数组有序
package com.atguigu.java;
/*
* 算法的考查:数组的复制、反转、查找(线性查找、二分法查找)
*
*
*/
public class ArrayTest2 {
public static void main(String[] args) {
String[] arr = new String[]{"JJ","DD","MM","BB","GG","AA"};
//数组的复制(区别于数组变量的赋值:arr1 = arr)
String[] arr1 = new String[arr.length];
for(int i = 0;i < arr1.length;i++){
arr1[i] = arr[i];
}
//数组的反转
//方法一: 两个元素的和是一个常数 length - 1
// for(int i = 0;i < arr.length / 2;i++){
// String temp = arr[i];
// arr[i] = arr[arr.length - i -1];
// arr[arr.length - i -1] = temp;
// }
//方法二:
// for(int i = 0,j = arr.length - 1;i < j;i++,j--){
// String temp = arr[i];
// arr[i] = arr[j];
// arr[j] = temp;
// }
//遍历
for(int i = 0;i < arr.length;i++){
System.out.print(arr[i] + "\t");
}
System.out.println();
//查找(或搜索)
//线性查找:
String dest = "BB";
dest = "CC";
boolean isFlag = true;
for(int i = 0;i < arr.length;i++){
if(dest.equals(arr[i])){
System.out.println("找到了指定的元素,位置为:" + i);
isFlag = false;
break;
}
}
if(isFlag){
System.out.println("很遗憾,没有找到的啦!");
}
//二分法查找:(熟悉)
//前提:所要查找的数组必须有序。
int[] arr2 = new int[]{-98,-34,2,34,54,66,79,105,210,333};
int dest1 = -34;
dest1 = 35;
int head = 0;//初始的首索引
int end = arr2.length - 1;//初始的末索引
boolean isFlag1 = true;
while(head <= end){
int middle = (head + end)/2; //此处直接除以2即可
if(dest1 == arr2[middle]){
System.out.println("找到了指定的元素,位置为:" + middle);
isFlag1 = false;
break;
}else if(arr2[middle] > dest1){
end = middle - 1;
}else{//arr2[middle] < dest1
head = middle + 1;
}
}
if(isFlag1){
System.out.println("很遗憾,没有找到的啦!");
}
}
}
数组元素的排序算法
排序算法的介绍
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aVGMsIug-1635843764705)(Java.assets/image-20211028113109507.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IC6SzWtA-1635843764706)(Java.assets/image-20211028113126918.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CCDR4QCe-1635843764707)(Java.assets/image-20211028113208330.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ad0VktXy-1635843764709)(Java.assets/image-20211028113219292.png)]
1、冒泡排序(BubbleSort)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rvpo1se8-1635843764710)(Java.assets/image-20211027215821457.png)]
package com.atguigu.java;
/*
* 数组的冒泡排序的实现
*
*/
public class BubbleSortTest {
public static void main(String[] args) {
int[] arr = new int[]{43,32,76,-98,0,64,33,-21,32,99};
//冒泡排序
//外层循环决定冒泡的次数,n个元素执行n-1次
for(int i = 0;i < arr.length - 1;i++){
//内层循环一次表示一个数冒泡到最后或者最前,这个数之后不参与排序
for(int j = 0;j < arr.length - 1 - i;j++){
if(arr[j] > arr[j + 1]){
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
//输出
for(int i = 0;i < arr.length;i++){
System.out.print(arr[i] + "\t");
}
}
}
2、快速排序(QuickSort)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Oap8K0Gz-1635843764711)(Java.assets/image-20211027215941253.png)]
package com.atguigu.java;
/**
* 快速排序
* 通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分关键字小,
* 则分别对这两部分继续进行排序,直到整个序列有序。
* @author shkstart
* 2018-12-17
*/
public class QuickSort {
private static void swap(int[] data, int i, int j) {
int temp = data[i];
data[i] = data[j];
data[j] = temp;
}
private static void subSort(int[] data, int start, int end) {
if (start < end) { //递归出口
//----------------------------------------------------------------
int base = data[start];
int low = start;
int high = end + 1; //后边--high,是先-1再读值
while (true) {
//此处不能改成 low < high,此种写法需要出循环时 high == low -1,此时再把high位置填上枢轴值
while (low < end && data[++low] - base <= 0)
;
while (high > start && data[--high] - base >= 0)
;
if (low < high) {
swap(data, low, high);
} else {
//此时high == low -1
break;
}
}
swap(data, start, high);
subSort(data, start, high - 1);//递归调用
subSort(data, high + 1, end);
//------------------------------------------------------------------
/* my
* 这种写法不用swap函数。 最后把base填入low或者high即可。因为出循环时low == high
int base = data[start];
int low = start;
int high = end;
while(low < high){
while(low < high && data[high] >= base){
--high;
}
data[low] = data[high];
while(low < high && data[low] <= base){
++low;
}
data[high] = data[low];
}
//出循环时候 low == high
data[low] = base;
//递归调用
subSort(data,start,low - 1);
subSort(data,low + 1,end);
*/
}
}
public static void quickSort(int[] data){
subSort(data,0,data.length-1);
}
//主函数
public static void main(String[] args) {
int[] data = { 9, -16, 30, 23, -30, -49, 25, 21, 30 };
System.out.println("排序之前:\n" + java.util.Arrays.toString(data));
quickSort(data);
System.out.println("排序之后:\n" + java.util.Arrays.toString(data));
}
}
老师写法过程:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kSZXhxnU-1635843764711)(Java.assets/image-20211028105328336.png)]
若内层wihle循环条件改成 low < high,将导致排序失败。此种写法需要出循环时 high == low -1,此时再把high位置填上枢轴值。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Le57FNK9-1635843764712)(Java.assets/image-20211028110310281.png)]
my:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YBZgVy35-1635843764713)(Java.assets/image-20211028105404082.png)]
Arrays工具类的使用
可以直接到API文档里边搜索Arrays
常用的几种工具类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TKZcvkrZ-1635843764714)(Java.assets/image-20211028112921238.png)]
package com.atguigu.java;
import java.util.Arrays;
/*
* java.util.Arrays:操作数组的工具类,里面定义了很多操作数组的方法
*
*
*/
public class ArraysTest {
public static void main(String[] args) {
//1.boolean equals(int[] a,int[] b):判断两个数组是否相等。
int[] arr1 = new int[]{1,2,3,4};
int[] arr2 = new int[]{1,3,2,4};
boolean isEquals = Arrays.equals(arr1, arr2);
System.out.println(isEquals);
//2.String toString(int[] a):输出数组信息。
System.out.println(Arrays.toString(arr1));
//3.void fill(int[] a,int val):将指定值填充到数组之中。
Arrays.fill(arr1,10);
System.out.println(Arrays.toString(arr1));
//4.void sort(int[] a):对数组进行排序。
Arrays.sort(arr2);
System.out.println(Arrays.toString(arr2));
//5.int binarySearch(int[] a,int key)
int[] arr3 = new int[]{-98,-34,2,34,54,66,79,105,210,333};
int index = Arrays.binarySearch(arr3, 210);
if(index >= 0){
System.out.println(index);
}else{
System.out.println("未找到");
}
}
}
数组使用中的常见异常
1、数组脚标越界异常(ArrayIndexOutOfBoundsException)
2、 空指针异常:NullPointerException
3、一旦程序出现异常,未处理,程序终止执行。
package com.atguigu.java;
/*
* 数组中的常见异常:
* 1. 数组角标越界的异常:ArrayIndexOutOfBoundsExcetion
*
* 2. 空指针异常:NullPointerException
*
*/
public class ArrayExceptionTest {
public static void main(String[] args) {
//1. 数组角标越界的异常:ArrayIndexOutOfBoundsExcetion
int[] arr = new int[]{1,2,3,4,5};
// for(int i = 0;i <= arr.length;i++){
// System.out.println(arr[i]);
// }
// System.out.println(arr[-2]);
// System.out.println("hello");
//2.2. 空指针异常:NullPointerException
//情况一:
// int[] arr1 = new int[]{1,2,3};
// arr1 = null;
// System.out.println(arr1[0]);
//情况二:
// int[][] arr2 = new int[4][];
// System.out.println(arr2[0][0]);
//情况三:
String[] arr3 = new String[]{"AA","BB","CC"};
arr3[0] = null;
System.out.println(arr3[0].toString());
}
}