随着时间的推移,内容也会发生变化。假设这一系列文章得到了一些回复,我也应该对有价值的内容做一些补充附录。
目前这一系列文章还没有明确的标题,结构明确后会再补充。
一、了解JAVA
Java是什么?
是高级编程语言。
Java是哪家公司开发的,现在属于哪家公司?
sun公司、Oracle公司。
Java父亲是谁?
詹姆斯.高斯林 Java能做什么?
基本上什么都能做,主要是开发互联网系统。
Java技术平台有哪些?
JavaSE(标准版),JavaEE(企业版),JavaME(小型版)
二、使用JAVA语言的前提
2.1 JDK的相关知识
1.什么是JDK?
JDK(Java Development Kit): Java开发工具包
2.JDK的作用?
必须安装JDK才能使用Java语言
PS.JDK中的LTS指的是?
long-term support:长期支持版
3.JDK的组成?
JDK由JVM,由开发工具组成的核心类库。
1.JVM是什么?
Java Virtual Machine:Java虚拟机, 真正运行Java程序地点。
2.核心类库是什么?
Java为程序员自己的程序调用自己的程序。
PS.JVM构成核心类库JRE。
JRE(Java Runtime Environment): Java工作环境。
PSS.理解记忆的想法是:
因为虚拟机可以用来尝试在日常生活中运行一些不知道是否安全的东西app什么,所以自己做的JAVA程序先在虚拟机(JVM)在里面运行没有问题。在学习的过程中,人们会调用各种准备好的方法,比如Scanner等等,所以在运行环境JRE中,核心类库也得有
什么是开发工具?
java,javac等
PSSS.这里需要提到JAVA开发的三个步骤:编写代码、编译代码和操作代码
具体过程:
首先编写代码,生成源代码文件(.java),之后使用javac编译代码,获得字节码文件(.class)然后使用java运行代码。
也因此,JAVA能够跨平台是因为不同的操作系统能够提供不同的JVM。
三、JAVA语言的基础
3.1 JAVA中的注释
名称 | 单行注释 | 多行注释 | 文档注释 |
样式 | //内容 | /*内容*/ | /**内容 */ |
快捷键(IDEA) | ctrl / | ctrl shift / | /** enter |
PS.编译后注释class文件中不存在。
3.2JAVA中的变量
1.变量是什么,有什么作用?
变量是内存中的一块区域。
它的功能是存储数据,可以替换存储的数据。
2.变量格式是什么?
数据类型 变量名称 = 初始值;
3.变量分类
1.局部变量 2.成员变量 2.1 实例成员变量 2.2 静态成员变量
数据类型
1.数据类型分类:
引用数据类型:String,自己写的类
基本数据类型:
数据类型 | 关键字 |
整数 | byte |
short | |
int(默认) | |
long | |
浮点数 | float |
double(默认) | |
字符 | char |
布尔 | boolean |
2.类型之间的转换
(1)自动类型转换
变量范围小,可直接赋值变量范围大。
【byte<short/char<int<long<float<double】
其中:int类型 , 加上L/l就是long类型,double类型,加上F/f就是float类型
在表达式中,小范围类型的变量将自动转换为当前大范围类型。
表达式的最终结果类型由表达式的最高类型决定。
在表达式中,byte、short、char 直接转换成int参与运算的类型。
(2)强制类型转换
类型范围大的数据或变量不能直接给类型范围小的变量赋值,会报错。
格式:数据类型 变量2 = (数据类型)变量1
数据(丢失)溢出可能是强制类型转换引起;
浮点型强转成整形,小数部分直接丢失,整数部分保留返回。
3.变量的基本特征是什么?
(1)变量只能存一个值
(2)可替换变量中存的值
PS.定义变量时应注意:
(1)使用前应声明变量
(2)变量声明后,其他类型的数据不能存储。
比如假设int类型变量无法保存double类型数据。
(3)变量定义可能没有初始值,但使用时必须给初始值。
例如,先随便定义一些 int a; int b;等等,但是当我想用a的时候,它必须有一个值。
(4)变量存在访问范围,同一范围的变量名不能重复。
3.3JAVA中的关键字
定义:在JAVA有特殊作用的词。
比如public之类的
3.4 JAVA中的标识符
定义:说白了就是名字
(1)由数字、字母、下划线(_)和美元符($)等组成
(2)不能以数字开头、不能是关键字、区分大小写
ps有关于什么驼峰模式我去找找看怎么弄比较好记
四、JAVA语言比基础稍微高一点的东西
4.1 各种进制的转换
(1)十进制转二进制的算法:除二取余法
4.2 计算机中数据的存储
除了1B = 8b这种单位之外,我们还要了解一下,计算机中会有很多文件形式,比如文本,声音与图像
字符在计算机中的存储有例如ASCII编码表的方式
PS字符’A’对应的数字是 65 ,字符’a’对应的数字是 97 ,字符’0’对应的数字是 48。这些可以记一记,说不定有用(?)
图片由像素点组成,像素点的颜色的表示也有很多方法,比如百分之几,或者0 - 255*255*255
声音的波纹每一点可由二进制的数据表示
4.3 数据的运算
4.3.1 运算符
4.3.1.1 通用内容
定义:对字面量或者变量进行操作的符号。
内容:+,-,*,/,%
PS.如果两个整数做除法,其结果一定是整数,因为最高类型是整数。
小案例题(后期案例应该也会整理出来)
Q:请将一个三位数的个位,十位,百位拆分开,打印在控制台
解题思路:这个题就是要利用数据类型的特点和运算符来算
以574举例
对于百位来说,574/100得到的是5.74,但是因为int类型是整数,所以5就有了
对于个位来说,574%10得到的是(商570)余4
把十位先整到个位的位置上,再用个位的计算方法来算就好了
最后总结一下:
个位 :数值 % 10
十位 :数值 / 10 % 10
百位 :数值 / 10 / 10 % 10
千位 :数值 / 10 / 10 / 10 % 10;
...
4.3.1.2 “+”用法
对于数字而言,就是数学的简单运算,而出现字符串的时候,就会变成连接运算
小案例题
Q:请写出以下输出语句的结果(大家复制IDE中的时候不要忘记写main方法,笑死。另外右键控制台的选项卡,在move to中可以把运行结果放右边,更好对比)
int a = 5;
System.out.println("abc" + 'a');
System.out.println("abc" + a);
System.out.println(5 + a);
System.out.println("abc" + 5 + 'a');
System.out.println(15 + "abc" + 15);
System.out.println(a + 'a');
System.out.println(a + "" + 'a');
System.out.println(a + 'a' + " abc");
System.out.println("abc" + a + 'a');
System.out.println("abc" + (a + 'a'));
在结果中我们可以发现,'a'在能够计算的时候,是按照97这个ASC2值来计算的,而字符串就单纯的被连接了起来。
4.3.1.3 自增自减运算符
符号 | 名称 | 作用 |
++ | 自增运算符 | 写在变量的前面或后面,使变量自身的值加1 |
-- | 自减运算符 | 写在变量的前面或后面,使变量自身的值减1 |
举例:int i = 0; i++
具体实用的案例:点一下大拇指,就多一个赞。
注意:
(1)++ 、-- 只能操作变量
(2)++、--如果不是单独使用(如在表达式中、或者同时有其它操作),放在变量前后会存在明显区别:
放在变量的前面,先对变量进行+1、-1,再拿变量的值进行运算.
放在变量的后面,先拿变量的值进行运算,再对变量的值进行+1、-1.
这个比较好记
比如我先设定一个 int i = 3;
然后让 int j = i++;
在看的时候,就是先看到i,我们把i先赋值给j,然后再让i自加,
那么此时的j=3,i=4;
而假设int j = ++i;
先看到的是++,那就给i先自加再说
最后j=4,i=4;
小案例题
请写出此代码的运算结果
int c = 10;
int d = 5;
int rs3 = c++ + ++c - --d - ++d + 1 + c--;
System.out.println(rs3);
System.out.println(c);
System.out.println(d);
在计算的时候应该做好笔记,这样不容易出错
例如画上表格
c | 10(初始值) | (2)11 | (3)12 | (11)11 | |||
d | 5(初始值) | (5)4 | (7)5 | ||||
rs3 | 不知道 | (1)10+ | (4)10+12 | (6)10+12-4 | (8)10+12-4-5 | (9)10+12-4-5+1 | (10)10+12-4-5+1+12 |
把变量名和初始值都写好
第一步(1):算的是c++,因为加号写在后面,所以先运算再自增,所以是10+
第二步(2):c的值变为11
大概这样理解
4.3.1.4 赋值运算符
即“=”
扩展:
符号 |
作用 |
说明 |
+= |
加后赋值 |
a+=b 等价于 a = (a的数据类型)(a+b); 将a + b的值给a |
-= |
减后赋值 |
a-=b 等价于 a = (a的数据类型)(a-b); 将a - b的值给a |
*= |
乘后赋值 |
a*=b 等价于 a = (a的数据类型)(a*b); 将a * b的值给a |
/= |
除后赋值 |
a/=b 等价于 a = (a的数据类型)(a/b); 将a / b的商给a |
%= |
取余后赋值 |
a%=b 等价于 a = (a的数据类型)(a%b); 将a % b的商给a |
PS.扩展的赋值运算符隐含了强制类型转换。
比如大的类型要强转才能赋值给小类型,下面的代码一个出错一个不出错
byte a = 2;
int b = 5;
a = a/b;
a /= b;
4.3.1.5 关系运算符
符号 |
说明 |
== |
a==b,判断a和b的值是否相等,成立为true,不成立为false |
!= |
a!=b,判断a和b的值是否不相等,成立为true,不成立为false |
> |
a>b, 判断a是否大于b,成立为true,不成立为false |
>= |
a>=b,判断a是否大于等于b,成立为true,不成立为false |
< |
a<b, 判断a是否小于b,成立为true,不成立为false |
<= |
a<=b,判断a是否小于等于b,成立为true,不成立为false |
关系运算符得到的值是布尔类型
4.3.1.6 逻辑运算符
功能:可以把多个条件的布尔结果放在一起运算,最终返回一个布尔结果。
符号 |
介绍 |
说明 |
& |
逻辑与 |
必须都是true,结果才是true; 只要有一个是false,结果一定是false。 |
| |
逻辑或 |
只要有一个为true、结果就是true |
! |
逻辑非 |
你真我假、你假我真。 !true=false 、 !false= true |
^ |
逻辑异或 |
如果两个条件都是false或者都是true则结果是false。两个条件不同结果是true。 |
短路逻辑运算符
符号 |
介绍 |
说明 |
&& |
短路与 |
判断结果与“&”一样。过程是左边为 false,右边则不执行。 |
|| |
短路或 |
判断结果与“|”一样。过程是左边为 true, 右边则不执行。 |
对比:
逻辑与 “&” 、逻辑或“|”: 无论左边是 false还是 true,右边都要执行。
实际开发中、常用的逻辑运算符还是:&& 、 || 、 !
4.3.1.7 三元运算符(我记得也叫三目运算符)
写法:条件表达式 ? 值1 : 值2;
运算流程:先计算表达式,若值为true就得到值1,false得到值2
小案例题
Q:请找出三个数中的最大值。
int a = 2;
int b = 5;
int c = 4;
int d = a > b ? a:b;
int max = d>c?d:c;
System.out.println(max);
不要忘了找个变量接一下结果。
4.3.1.8 运算符的优先级
因为网络上很好查到,所以我这里就来整理一下记忆的思路
优先级最高的是括号,这个很好理解,就是肯定先括起来谁就先算谁,我们一般的习惯也是这样
第二高的是!非,~取反,++,--。也就是对这个数据本身有变化意涵的都会更先执行。
第三高的是乘除取余,数学规律
第四是加减,数学规律
小案例题
Q:请写出代码的输出结果
System.out.println(10 > 3 || 10 > 3 && 10 < 3);
System.out.println( (10 > 3 || 10 > 3 ) && 10 < 3);
4.4 程序流程控制
程序执行的常见形式有顺序结构,分支结构,循环结构
顺序结构是默认的执行流程
4.4.1分支结构
分支结构是通过判断某条件是否成立来选择某段程序执行
4.4.1.1 if语句
if语句的格式与执行流程:
格式1:
if (条件表达式) {
语句体;
}
执行流程:首先判断条件表达式的结果,如果为true执行语句体,为 false 就不执行语句体。
PS.if 语句中,如果大括号控制的只有一行代码,则大括号可以省略不写。
格式2:
if (条件表达式) {
语句体1;
} else {
语句体2;
}
执行流程:首先判断条件表达式的结果,如果为true执行语句体1,为 false 就执行语句体2。
格式3:
if (条件表达式1) {
语句体1;
} else if (条件表达式2) {
语句体2;
} else if (条件表达式3) {
语句体3;
} . . . else {
语句体n+1;
}
执行流程:先判断条件1的值,如果为true则执行语句体1,分支结束;如果为false则判断条件2的值 如果值为true就执行语句体2,分支结束;如果为false则判断条件3的值 ... 如果没有任何条件为true,就执行else分支的语句体n+1。
小案例题
1.设置几个考试成绩分数段,不同成绩打印出不同的奖惩结果。
2.设置一个正确的密码,让用户输入密码,当用户输入密码正确时打印“正确”,错误时打印“错误”
4.4.1.2 switch语句
相比起if语句,它的结构和格式更好看一些,适合做值匹配的分支
格式:
switch(表达式){
case 值1:
执行代码...;
break;
case 值2:
执行代码...;
break;
…
case 值n-1:
执行代码...;
break;
default:
执行代码n;
}
这里的default还挺容易被忘掉的。
执行流程:先执行表达式的值,拿着这个值去与case后的值进行匹配。 匹配哪个case的值为true就执行哪个case,遇到break就跳出switch分支。 如果case后的值都不匹配则执行default代码。
注意:
(1)表达式类型只能是byte、short、int、char,JDK5开始支持枚举,JDK7开始支持String、不支持double、float、long。
这是因为假设设定一个double类型的变量,double a = 0.1+0.2;它输出的结果会是0.30000000……这样
(2)case给出的值不允许重复,且只能是字面量,不能是变量。
(3)不要忘记写break,否则会出现穿透现象。
就是判断符合结果却没有跳出这个分支,而是继续向下走。
但穿透其实也可以利用
例如case1和case2要执行的代码一样的话,我们可以写成这样,就会更加简单
switch(表达式){
case 值1:
执行代码1;
case 值2:
执行代码2;
…
case 值n-1:
执行代码n-1;
break;
default:
执行代码n;
// break;
}
4.4.2 循环结构
循环结构是重复执行某段程序多次
4.4.2.1 for循环
格式:
for (初始化语句; 循环条件; 迭代语句) {
循环体语句【也就是重复执行的代码】;
}
案例:
输出3次HelloWorld
for (int i = 0; i < 3; i++) {
System.out.println("Hello World");
}
执行的流程:
循环一开始,执行int i = 0 一次。 然后判断循环条件:0 < 3 返回true ,进入到循环体中执行输出 :helloWorld ,
然后执行迭代语句i++ , 此时i=1了。
然后判断循环条件:1 < 3 返回true ,进入到循环体中执行输出 :helloWorld ,
然后执行迭代语句i++ , 此时i=2了。
然后判断循环条件:2 < 3 返回true ,进入到循环体中执行输出 :helloWorld,
然后执行迭代语句i++ , 此时i=3了。
然后判断循环条件:3 < 3 返回false, 循环立即结束
小案例题
(1)求1-5之间的数字和,并把求和结果在控制台输出。
解题思路:
写循环语句循环1-5
并设置一个变量来累加数据
(2)求1-10之间的奇数和,并把求和结果在控制台输出。
解题思路:判断是否为奇数,就是看这个数字除以二的余数是一还是零
(3)在控制台输出所有的“水仙花数”
【水仙花数是一个三位数。水仙花数的个位、十位、百位的数字立方和等于原数】
解题思路:之前我们已经练习过如何得到三位数的个位,十位,百位。然后通过循环语句遍历所有的三位数,再使用if语句判断它是否是水仙花数,如果是的话输出就好了
(4)在控制台输出所有的“水仙花数”,输出水仙花数的个数
解题思路:要知道个数,只需要再设置一个变量,让它自增
4.4.2.2 while循环
格式:
初始化语句;
while (循环条件) {
循环体语句【被重复执行的代码】;
迭代语句;
}
什么时候用for循环,什么时候用while循环?
它们在功能上是完全一样的,for能解决的while也能解决。
使用规范是:知道循环几次:使用for;不知道循环几次建议使用:while。
小案例题
世界最高山峰是珠穆朗玛峰(8848.86米=8848860毫米),假如我有一张足够大的纸,它的厚度是0.1毫米。请问,折叠多少次,可以折成珠穆朗玛峰的高度。
解题思路:
不知道循环几次所以使用while。
纸的初始厚度为0.1,对折一次翻一倍。
4.4.2.3 do while循环
do-while循环的特点:一定会先执行一次循环体。
格式:
初始化语句;
do {
循环体语句;
迭代语句;
} while (循环条件);
使用案例 :先执行的这种循环在实际使用案例中就像抢票一样,抢了之后判断一下抢到没有。
三种循环的对比
for循环 和 while循环(先判断后执行)
do...while (第一次先执行后判断)
for循环中,控制循环的变量只在循环中可以使用。While循环中,控制循环的变量在循环后还可以继续使用。
4.4.2.4 死循环
定义:一直循环的执行下去,如果没有干预不会停止下来。
格式:
for(;;) {
System.out.println("Hello World"); }
【while的最为常用】
while(true) {
System.out.println("Hello World");
}
do {
System.out.println("Hello World");
} while (true);
PS.在IDEA中,添加死循环的快捷键是Ctrl+alt+t
小案例题:
设定一个系统密码,请用户不断的输入密码验证,如果验证不对就输出:密码错误,验证成功输出:欢迎进入系统,并停止程序。
解题思路:
将输入与验证都包含进死循环当中,if判断正确的话使用break跳出循环
4.4.2.5 循环嵌套
循环之间是可以嵌套的,例如:
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 5; j++) {
System.out.println("这是一个循环嵌套");
}
}
嵌套循环的特点:外部循环每循环一次,内部循环全部执行完一次。
小案例题:
在控制台输入5行5列的*号组成的矩形
解题思路:
内循环负责打出5列的*,外循环负责换行
4.4.3 跳转控制语句
break : 跳出并结束当前所在循环的执行。 只能用于结束所在循环, 或者结束所在switch分支的执行。
continue: 用于跳出当前循环的当次执行,进入下一次循环。只能在循环中进行使用。
小案例题:
你是一位攘夷志士,为了成为桂先生的心腹每天兢兢业业,这一天,桂先生安排你在未来五天每天去江户公园投喂六只猫咪,你领命,每天认真撸猫并拍摄照片上传到攘夷志士公众号做宣传。
(1)你投喂到了第三天,可恶的税金小偷最近四处巡逻,桂先生为了你的安全着想,让你不要去了。
解题思路:外循环是控制五天的,内循环是控制投喂六只猫咪的。但由于第四天的时候不能继续投喂了,因此当i等于4时使用break跳出循环。
(2)你投喂到了第三天,家里的速食荞麦面吃光了,需要进行补充,而超市特价还能顺便买些牛肉来吃火锅,桂先生派你去抢购食材,这一天就别去投喂猫咪了。
解题思路:外循环是控制五天的,内循环是控制投喂六只猫咪的。但由于第四天的时候有事,无法投喂了,因此当i等于4时使用continue跳出本次循环,明天继续投喂。
4.5 随机数Random
功能:用于在程序中生成随机数
使用方法:
(1)导包:告诉程序去JDK的哪个包中找随机数技术【至少IDEA会帮我们导进来,我们不用管】
(2)new一个随机数对象
Random r = new Random();
(3)调用随机数的功能来获取随机数。
int number = r.nextInt(10);
用int来接的话就调用nextInt,并且nextInt(n) 功能只能生成: 0 至 n-1之间的随机数,不包含n。
如果想生成3到15之间的随机数要怎么做呢?
解法:
先给3和15都减3,就会变成0到12,然后写
int number = r.nextInt(13);
这样就能得到0到12的随机数了
然后再加上3
int number = r.nextInt(13)+3;
小案例题:
随机生成一个1-100之间的数字,让用户来猜,猜大提示过大,猜小提示过小,直到猜中结束游戏
解题思路:先随机生成一个符合条件的数字,然后把整个输入和if判断都放进死循环里,猜到了的话就break跳出循环。
4.6 数组
定义:用来存储一批同种类型数据的容器。
例如我定义一个int类型的数组
int arr[] = {1,2,3};
里面只能存储int类型的数据
PS.这个[]写在int后面或者数组名后面都行,因为我最开始学的C语言,所以写后面比较习惯
4.6.1 静态化初始数组
也就是:定义数组的时候直接给数组赋值。
4.6.1.1 数组基本知识
书写格式:数据类型[] 数组名 = new 数据类型[]{元素1,元素2 ,元素3… };
eg. int[] ages = new int[]{12, 24, 36};
简化后的书写格式:数据类型[] 数组名 = { 元素1,元素2 ,元素3,… };
eg. int[] ages = {12, 24, 36};
数组的原理
以int[] ages = {12, 24, 36};这个数组为例
首先在内存中开辟一块存储数组变量ages的区域,然后再开辟一块连续的区域存储对象{12, 24, 36}【可以想象他们一人一个房间】它们有一个地址【门牌号】
int[] ages = {12, 24, 36};语句是从右往左执行的,这个等于号就会把【门牌号】交给变量来存储。
在使用过程中,变量可以通过地址找到数组,访问数据
PS.数组也是引用类型。【就是其中装着地址】
4.6.1.2 数组的访问
访问数组中元素的格式:数组名称[索引]
为数组赋值:数组名称[索引] = 数据;
数组的最大索引值为:数组名. length – 1
PS.在元素个数大于零的情况下才能使用。
补充:数组一旦定义出来,长度、类型就固定了。
4.6.2 动态化初始数组
也就是:定义数组的时候只确定元素的类型和数组的长度,之后再存入具体数据。
书写格式:数据类型[] 数组名 = new 数据类型[长度];
eg. int[] arr = new int[3];
对比:两种数组定义时的特点和场景有什么区别?
当前已经知道存入的元素值,用静态初始化。
当前还不清楚要存入哪些数据,用动态初始化。
两种格式的写法是独立的,不可以混用。
eg. int[] arrs = new int[3]{30,40,50}; 这样是错的。
两个数组变量可以同时指向一个数组对象,也就是两个数组变量保存着同一个数组地址
4.6.3 数组使用时可能存在的问题
如果访问的元素位置超过最大索引,执行时会出现ArrayIndexOutOfBoundsException(数组索引越界异常)
如果数组变量中没有存储数组的地址,而是null, 在访问数组信息时会出现NullPointerException(空指针异常)
元素默认值规则
数据类型 | 具体类型 | 默认值 |
基本类型 | byte、short、char、int、long | 0 |
float、double | 0.0 | |
boolean | false | |
引用类型 | 类、接口、数组、String | null |
4.6.3 数组遍历
用案例来展示如何遍历数组
eg.int[] ages = {20, 30, 40, 50};
for (int i = 0; i < ages.length; i++) {
System.out.println(ages[i]);
}
小案例题:
(1)在本周壁外调查的过程中,让宝的巨人击杀数量分别是:3,4,2,0,5匹,请计算出让宝本周击杀数量的总和。
解题思路,先将击杀数量存进数组中,对数组进行遍历,将各个索引中的数据累加起来。
(2)训练兵吃晚饭的时候在聊天,说到各自的身高,大家公认贝贝(190)最高,阿尼(153)翻白眼不想理他们,让宝(175)撑着脸道:“我也就比某个赶着去死的家伙高5厘米而已”。而对方反击“确实比不了你,脸上额外增加了五厘米。”此时利歪(只是想迫害一下小矮子)踹门而入。
请通过数组求以上角色的身高最大值。
解题思路:先将大家的身高放进数组里{190,153,175,170,160,},设定一个max变量存储数组中第一个元素,遍历数组进行比较,将最大值存入max中,最后输出max
(3)写一个小游戏,后台随机生成1-30之间的五个数字,用户可以输入数字来猜,未猜中提示:“未命中”,并继续猜测。猜中提示:“运气不错,猜中了”,并输出该数据第一次出现的索引位置,最后把数组中的5个数据都输出, 然后结束本游戏。
解题思路:使用Random生成五个随机数存储进数组里。在死循环中让用户输入数字,遍历数组寻找是否与用户输入的数字匹配,假设匹配就break
(4)同人大手大发慈悲准备给每位S级英雄画同人图,(为了简单大家可以挑一些自己喜欢的英雄,比如油腻假面,刘海大婶,邦古老头什么的),但是大手说要随机,根据S级英雄的等级数字来随机摇号,最后输出一组随机的排名。
解题思路:先将s级英雄的排名存入数组,遍历数组,并通过Random随机索引值,让i位置的数据与随机的索引位置的数据交换,最终得到新的数组。
【随机交换排名也可以用在洗牌当中】
对元素交换来一点小小的补充
比如要交换的是 int a = 1;int b = 2;
我们可以创建一个int c = 0;
然后:
c = a;
a = b;
b = c;
也可以:
a = a+b;
b = a-b;
a = a-b;
4.7 java内存的分配
JAVA中的内存可以分为五块区域
栈
堆
方法区
本地方法栈
寄存器
就像家里有客厅厨房一样,每个地方有每个地方的用途,易于管理和维护,提高性能
方法区:是字节码文件加载时进入的内存【.class文件】
栈内存:方法运行时进入的内存,变量也在其中
堆内存:new的那些对象,在这块内存中开辟空间并分配地址
4.8 方法
定义:方法是一种语法结构,它可以把一段代码封装成一个功能,以方便重复调用。
例如 main方法
为什么要使用方法?
(1)提高了代码的复用性。
假如一个功能,在这个地方也要用,那个地方也要用,只写一遍就更简单一些
(2)让程序的逻辑更清晰。
对一个庞大的系统而言,会有许许多多的方法,要是不调用方法,而是将这些代码放在例如switch语句中,就显得非常凌乱,而调用某个方法则只需要一行。
4.8.1 定义方法
书写格式:
修饰符 返回值类型 方法名( 形参列表 ){
方法体代码【需要执行的功能代码】
return 返回值;//可能有可能没有
}
定义方法时真正需要关注的就两点:1、分析方法是否需要申明返回值类型;2、分析方法是否需要接收参数
PS.形参列表可以有多个,甚至可以没有; 如果有多个形参,多个形参必须用“,”隔开,且不能给初始化值。
如果方法不需要返回结果,返回值类型必须申明成void(无返回值), 此时方法内部不可以使用return返回数据。
方法如果没有参数,或者返回值类型申明为void可以称为无参数、无返回值的方法,依次类推。
举例:一个求和的方法:
public static int add ( int a , int b ){
int c = a + b;
return c;
}
返回值类型和返回值的类型要一致
4.8.2 调用方法
书写格式:
方法名(假如有要传递的参数就写在这里);
举例:调用求和的方法:
int sum = add(10, 20); //用一个int类型的变量接一下返回值
4.8.3 具体使用方法的注意事项
(1)方法的编写顺序无所谓。
假如你先写main方法,再写别的方法也可以。
(2)方法与方法之间是平级关系,不能嵌套定义。
也就是方法里面不能写别的方法。
(3) return语句下面,不能编写代码,因为永远执行不到,属于无效的代码。
return了就直接把值返回了,后面就执行不下去了。
(4)方法不调用就不执行, 调用时必须严格匹配方法的参数情况。
就像你不叫别人别人也不理你,然后你给人家寄信也得把地址写对,人家是int类型,你别传double类型
(5)有返回值的方法调用时可以选择定义变量接收结果,或者直接输出调用,甚至直接调用;无返回值方法的调用只能直接调用。
小案例题:
(1)定义一个方法,方法中计算出 1到n的和并返回。
解题思路:它说了要返回,就肯定有返回值,它有n,说明肯定要传参。计算用for循环来累加就行了。
(2)写一个能判断某数是奇数还是偶数的方法。
解题思路:某数肯定还是让你输入的,所以要传参,但是返回不返回都可以,因为在本方法里面输出和在main方法(或调用本方法的方法)里面输出都行。
(3)给一个数组求最大值的例题,也可以把求最大值的过程单独成一个方法。
解题思路:传参要把数组传过去,最大值应该返回
4.8.4 调用方法在内存中是怎么弄的?
方法是放在方法区中的,被调用的时候,需要进入到中运行
方法没有被调用的时候,在方法区中的字节码文件中存放
被调用需要进入栈内存中运行
所以可以将弹夹看做方法区,子弹看做方法,枪膛看做栈内存
4.8.5 方法的参数传递
4.8.5.1 基本类型的参数传递
值传递 : 在传输实参给方法的形参的时候,并不是传输实参变量本身, 而是传输实参变量中存储的值,这就是值传递。
实参:如在方法内部定义的变量。
形参:如在定义方法时,“()”中所声明的参数
4.8.5.2 引用类型的参数传递
也是值传递,但传递的是参数传输存储的地址值。
小案例题:
(1)写一个方法,要求将数组输出成:“该数组内容为:[1, 2, 3, 4, 5]”这样
解题思路:它肯定要得到一个数组才能输出,所以需要传参,但是可以不返回
需要遍历数组才能拿到数据
输出时,假设不是最后一个数,就输出数字加逗号,如果是最后一个数字应该输出数字+反中括号。
(2)设计一个方法可以接收整型数组,和要查询的元素值;最终要返回元素在该数组中的索引,如果数组中不存在该元素则返回 -1。
解题思路:要传参,要返回值。遍历数组,先展示一下有哪些元素,然后遍历数组,让用户输入的数据和数组中的数据进行匹配,把i返回回来。
(3)设计一个方法比较两个整型数组是否一样。【如果两个数组的类型,元素个数,元素顺序和内容是一样的我们就认为这2个数组是一模一样的。】返回true或者false。
解题思路:需要传参,需要返回值。可以定义一个方法先比较他们的元素个数是否相等,再比较相同位置的元素是否相等,如果两个都是true那么证明他们相等。
4.8.6 方法的重载
定义:同一个类中,出现多个方法名称相同,但是形参列表是不同的,那么这些方法就是重载方法。
举例:利根川老师每天的工作量很大,可能要给黑服们开会,可能要被兵藤会长制裁,偶尔有空去打高尔夫球。
public class Tonegawa {
/**(1)默认被制裁。*/
public static void work(){
System.out.println(“默认被兵藤会长制裁!");
}
/** (2)还要开会。 */
public static void work(String location){
System.out.println("在"+location+"给黑服开会");
}
/**(3)开会之后去打高尔夫*/
public static void work(String location ,double times){
System.out.println("在"+location+"给黑服开会.打"+times+"小时高尔夫球");
}
}
方法重载的作用 :可读性好,方法名称相同提示是同一类型的功能,通过形参不同实现功能差异化的选择,这是一种专业的代码设计。
方法重载的识别技巧 :只要是同一个类中,方法名称相同、形参列表不同,那么他们就是重载的方法,其他都不管!(如:修饰符,返回值类型都无所谓)
形参列表不同指的是:形参的个数、类型、顺序不同,不关心形参的名称。
return关键字单独使用
效果 :可以立即跳出并结束当前方法的执行。
对比记忆:
- return; 跳出并立即结束所在方法的执行。
- break; 跳出并结束当前所在循环的执行。
- continue; 结束当前所在循环的当次继续,进入下一次执行。
五、面向对象
在学习面向对象的时候,可以把面向对象和面向过程做一个对比
面向过程,就像我们之前做过的很多练习,桂先生让你去投喂猫咪,你先干了前三天,第四天出事了,那我们就得用continue跳出来。每一步都很明确。
面向对象,是将自己作为一个旁观者,我来命令谁干什么事情,他们自己去做事。也就是可以把面向看做“找”,把对象看做“谁”,找谁来干活。
在这种情况下,面向对象与面向过程的优缺点是什么?
优点 | 缺点 | |
面向过程 | 简单 | 维护性差 |
面向对象 | 可扩展性强,维护成本低 | 新手上手难 |
在之前做例题的时候,我们已经使用过例如:
System.out.println();
Scanner
Random
这其实就是一种面向对象
5.1 类
定义:是对象共同特征的描述;
我们可以将类想象成一个设计图,根据这个设计图可以制造出具体的对象,也就是真实存在的具体实例。
例如
Random r = new Random();
Random就是一个类型,根据Random这个设计图,new一个新的r对象出来
5.1.1 设计类
总体格式:
public class 类名 {
1、成员变量Field(代表属性,一般是名词)
2、成员方法Method(代表行为,一般是动词)
3、构造器Constructor (初始化一个类的对象并返回地址)
4、代码块
5、内部类
}
我们可以用一个案例来学习
今天是5.26日,还有一个月就是桂先生的生日了,我想整一张猫咪设计图,生成许多猫咪送给桂先生做生日礼物。
public class Cat{
}
public class Cat{
String name;//人类为了区分猫咪,会给它们起名字
String color;//每只猫咪都有不同的花色
int age;//至少按周岁比较好区分年龄
}
public class Cat{
String name;//人类为了区分猫咪,会给它们起名字
String color;//每只猫咪都有不同的花色
int age;//至少按周岁比较好区分年龄
public void play(){
}//动物有玩耍的天性
public void eat(){
}//猫咪至少要吃饭
}
书写格式:类名 对象名 = new 类名();
也就是:Cat c = new Cat();
访问属性: 对象名.成员变量
c.color
访问行为: 对象名.方法名
c.play
补充:
类名首字母建议大写,且有意义
一个Java文件中可以定义多个class类,但只能一个类是public修饰,而且public修饰的类名必须成为代码文件名。 实际开发中建议还是一个文件定义一个class类。
成员变量的完整定义格式是:修饰符 数据类型 变量名称 = 初始化值; 一般无需指定初始化值,存在默认值。
修饰符比如 private。默认值就是之前数据类型的默认值。
1.对象是放在哪个位置的?
堆内存中
2. Cat c = new Cat(); c变量名中存储的是什么?
存储的是对象在堆内存中的地址。
3.成员变量的数据放在哪里,存在于哪个位置?
对象中,存在于堆内存中。
4.当堆内存中的对象,没有被任何变量引用(指向)时,就会被判定为内存中的“垃圾”。Java存在自动垃圾回收器,会定期进行清理。
5.1.2
定义:定义在类中的,可以用于初始化一个类的对象,并返回对象的地址。
书写格式:
修饰符 类名(形参列表){
...
}
当形参列表存在的时候,称为有参数构造器。不存在称为无参数构造器
无参数构造器(默认存在的):初始化对象时,成员变量的数据均采用默认值。
有参数构造器:在初始化对象的时候,同时可以接收参数为对象进行赋值。
PS.至少在IDEA中,构造器是可以右键一下自动生成的
调用构造器得到对象
书写格式:类 变量名称 = new 构造器;
也就是之前写过的:Cat c = new Cat();
如果要传参的话:Cat c = new Cat("咪咪","玳瑁",1);
补充:
任何类定义出来,默认就自带了无参数构造器,写不写都有。
一旦定义了有参数构造器,那么无参数构造器就没有了,如果还想用无参数构造器,此时就需要自己手写一个无参数构造器了。
防忘记,稍微整理一下
public class Cat {