目录
while语句 VS do-while语句 VS for语句
Java概念
Java发展史
发布时间
1995年
领导发布者
James Gosling
所属公司
SUN公司
发展历程
- 1990年,在SUN公司推出“Green计划”,由James Gosling领导设计了Oak语言(Java语言前身)。
- 1995年,,Java正式诞生,推出了Java1.0以及开发工具包JDK1.0。
- 2004年,Java推出了Java5,此后都以JavaX命名。
- 2009年,Sun公司被Oracle收购,之后都由Oracle进行更新维护。
- 2014年,推出了Java8,是当前最流行稳定的Java版本,也是长期维护版LTS。
- 当前长期维护版为Java8、Java11和Java17。
Java的分类
JavaME
JavaME被称为Java微型版,用于开发移动应用。在早期的塞班系统中会使用,但如今基本已经淘汰。
JavaSE\笔记
JavaSE\笔记被称为Java标准版,是Java的核心和基础,也是JavaME和JavaEE的核心。可以用于开发桌面端
程序。如IDEA就是用Java开发的。
JavaEE
JavaEE被称为Java企业版,用于开发WEB应用。Java的流行全靠JavaEE。WEB应用如门户网站、电子商务、电子政务等服务器都是由JavaEE实现。
Java的定义
Java是一门跨平台、“半解释半编译”的“面向对象”语言。
Java的优点
- 面向对象
- 半解释半编译
- 开源
- 简单
- 多线程
- 安全
Java跨平台运行的原理
核心
安装Java后,再安装的JVM(Java Virtual Machine称为Java虚拟机),它会解释源文件编译过后的.class字节码文件。此JVM能够在不同的平台上正常运行。
Java的安装以及环境搭建
1.下载JDK安装
根据自己设备选择对应的版本(常用的电脑设备要注意32位的操作系统和64位的操作系统)从Oracle官网下载,建议下载LTS长期维护版本。Java8、Java11、Java17是LTS版。
2.配置计算机的环境变量
- 新建系统变量:此电脑==》右键属性==》高级系统设置==》环境变量
- 配置PATH
3.测试环境(安装是否成功)
在完成以上两步之后,在控制台输入“java -version”,回车之后能够显示安装的版本号,则为安装成功。
Java程序的运行过程
一个简单Java程序的组成
public class HelloWord {
//主方法,是每个程序的入口函数,只有一个,如果没有将无法正常执行。
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
运行过程
通过javac命令进行编译,生成同名的.class字节码文件,在虚拟机上解释该字节码文件运行。
数据类型
原始类型
- 整型
类型名 所占字节大小(所占位数) 范围 byte 1字节(8位) -128~127 short 2字节(16位) -32768~32767 int 4字节(32位) -2147483648~2147483647 long 8字节(64位) -2^63至2^63-1 - 浮点型
类型名 所占字节大小(所占位数) 范围 float 4字节(32位) double 8字节(64位) - 字符型
类型名 | 所占字节大小(所占位数) | 范围 |
---|---|---|
char | 2字节(16位) | 汉字:[0x4e00,0x9fa5](或十进制[19968,40869]) 数字:[0x30,0x39](或十进制[48, 57]) 小写字母:[0x61,0x7a](或十进制[97, 122]) 大写字母:[0x41,0x5a](或十进制[65, 90]) (默认是Unicode编码) |
- 布尔型
类型名 所占字节大小(所占位数) 范围 boolean false/true
引用类型
- 数组
- 类
- 接口
类型转换
- 自动类型转换
public class HelloWord { public static void main(String[] args) { //小字节类型数据可以直接保存到大字节类型的变量中。 char num1 = 64; int num2 = num1; System.out.println(num2);//结果:64 } }
public class HelloWord { public static void main(String[] args) { //整型数据可以直接保存到浮点型变量中。 int num1 = 64; double num2 = num1; System.out.println(num2);//结果:64.0 } }
变量
变量的概念
保存数据的内存区域,其中的数据可以变化。
定义变量
语法规范
int num;//数据类型 变量名
变量赋值
int num;//必须先定义变量名
num = 99;//变量名 = 值
注意点
- 等号右边的值有默认的数据类型
- 整数默认为int,小数默认double类型。
变量初始化
int num = 99//数据类型 变量名 = 值
注意点
- 变量需要自定义、赋值后才能使用。
int num; System.out.println(num);//错误代码演示,结果会报未初始化的错误
运算符
算术运算符
符号 | 名称 | 作用(场景) |
---|---|---|
+ | 加 |
|
- | 减 | 只能用于数值型数据。 |
* | 乘 | 只能用于数值型数据。 |
/ | 除 | 只能用于数值型数据。(如果两个整数相除,结果只保留整数部分(商)) |
% | 取余 | 只能用于数值型数据。(商一定是整数) |
注意点
- 需要两个操作数参与,如果有浮点数参与运算,结果为浮点型。
- 如果同时多个符号—起使用,遵循数学中的四则运算规则,先乘除,后加减。
- 运算时最终结果的数据类型,以所有参与运算的操作数中所占字节最大的类型为准。
System.out.println(8-2+3/2.0%10);//结果 7.5
关系运算符
符号 | 名称 | 作用(场景) |
---|---|---|
> | 大于 | 左边的数值(表达式)比右边的数(表达式)大 |
< | 小于 | 左边的数值(表达式)比右边的数(表达式)小 |
>= | 大于等于 | 左边的数值(表达式)比右边的数(表达式)大或相等 |
<= | 小于等于 | 左边的数值(表达式)比右边的数(表达式)小或相等 |
!= | 不等于 | 左边的数值(表达式)与右边的数(表达式)不相等 |
== | 等于 | 左边的数值(表达式)与右边的数(表达式)相等 |
注意点
-
在关系运算符两边都需要操作数 ,且计算结果必为布尔型boolean。
-
==用于判断相等,=用于赋值
-
==用于比较两个原始类型的值或引用类型的内存地址
-
关系运算的结果为true/false
逻辑运算符
符号 | 作用 | 名称 | 说明 |
---|---|---|---|
&& | and | 逻辑与 |
|
|| | or | 逻辑或 |
|
! | not | 逻辑非 | 单目运算符,只需要一个表达式参加运算。在一个表达式前面使用或导致表达式最终结果取反。 |
注意点
-
&&和||也称为短路运算。如果能通过第一个表达式决定最终的结果,则不用判断第二个表达式
-
通常情况下,使用&&和||提高代码执行效率。
赋值、复合赋值运算符
符号 | 名称 | 类型 | 作用 |
---|---|---|---|
= | 赋值 | 赋值运算符 | 讲符号右边变量或表达式的值给左边的变量 |
+= | 加等于 | 复合运算符 | num1+= 1 相当于 num1 = num1 + 1; |
-= | 减等于 | num1 -=1 相当于 num1 = num1 - 1; | |
*= | 乘等于 | a *= b + c 相当于 a = a *( b + c) | |
/= | (整)除等于 | a /= b + c 相当于 a = a /( b + c) | |
%= | 取余等于 | a %= 10 相当于 a = a % 10 |
注意点
- 复合赋值运算的流程是:将符号两端的整体进行对应的算术运算后,将结果赋值给符号左侧的变量中。
自增、自减运算符
符号 | 名称 | 作用 |
---|---|---|
++ | 自增1 | 结果+1 |
-- | 自减1 | 结果-1 |
注意点
-
a++或++a相当于a+=1或a=a+1。
- 如果++或--独立成行使用,无论符号在前在后,都将结果+1或-1。
int num=9;
// num++;
++num;
System.out.println(num);//10
- 如果++或--不是单独成行(分为两种情况:在前和在后)
int a=6; if(a++>6){//符号在后,先使用,即6>6不成立 } S ystem.out.println(a);//a最终会+1,7 int b=4; if(--b==3){//符号在前,先计算,即3==3成立 } S ystem.out.println(b);//3 int num=10; System.out.println(num++ + ++num);//10 + ++11 => 22 int num2=10; System.out.println(num-- - --num);//10 - --9 => 2
条件元算符
语法格式
表达式1?表达式2:表达式3;
注意点
- 也叫三目表达式,必须有三个表达式参与。作用相当于if的双分支语句。
- 首先运算表达式1,如果结果为true,执行问号后的表达式2;
- 如果结果为false,执行冒号后的表达式3。
- 整个表达式的最终结果为表达式2或表达3。
运算符的优先级
小括号>>单目运算符>>算术运算符>>关系运算符>>逻辑运算符>>条件运算符>>赋值/复合赋值运算符
//判断一个年份是否是闰年
//四年一闰,百年不闰,四百年再闰
//year是"4的倍数但不是100的倍数,或者是400的倍数"
int year =2022;
char result = (year%4==0&&year%100!=0)||year%400==0?'闰':'平';
System.out.println(result+"年");
条件语句
if语句
单分支if语句
只有满足条件才实现大括号里面的语句
if(判断条件){//判断条件的结果为布尔值
条件满足时执行的代码
}
双分支if语句
满足条件实现if大括号里面的语句,不满足条件实现else里面的语句
if(判断条件){
条件满足时执行的代码
}else{
条件不满足时执行的代码
}
多分支if语句
满足对应一个条件,实现对应大括号里面的语句。
if(判断条件1){
如果判断条件1满足时执行
}else if(判断条件2){
如果判断条件2满足时执行
}else if(判断条件3){
如果判断条件3满足时执行
}else{
如果所有条件都不满足时执行
}
if嵌套语句
满足多个层次的判断,进入对应的大括号实现语句。
if(){
if(){
满足多层次条件,实现的代码1
}
}else{
if(){
满足多层次条件,实现的代码2
}
}
注意点
- 嵌套不要太多,会影响可读性和代码整洁性。
- if嵌套可以被if()return 替换,其目的就是在程序满足一个关键性的条件时,不再执行后续代码,以此提高程序效率。
int a = 3, b = 4, c = 4; //判断是否是三角形 if ((a + b) <= c || (a + c) <= b || (c + b) <= a) { return; } //判断是否是等腰三角形 if (a == b || a == c || b == c) { System.out.println("是等腰三角形"); }
switch语句(开关语句)
经过一个确切的变量值能选择对应语句执行。
switch(变量){//要判断的变量,只能是非long整型、字符型char和字符串String和枚举类型
case 值:
//如果变量的值与当前case的值匹配,执行这里的代码
break;
case 值:
//如果变量的值与当前case的值匹配,执行这里的代码
break;
...
default:
//如果没有任何值与变量的值匹配,执行这里的代码
break;
}
注意点
- swtich小括号中的变量只能是非long的整型、字符型char、字符串String和枚举类型
- 小括号中的变量类型要与case后的值的类型相匹配
- 如果有某个case后的内容和变量值匹配,执行case后的代码,如果没有任何case匹配,执行
default后的代码 - break和default可以省略。如果不写break,在某个case匹配时,执行完相应的代码后继续执行后续case后的代码,直到遇到break或没有代码为止
- 如果多个case后执行的内容一致,可以省略break,将统一要做的代码放在最后的case后
if语句 VS swich语句
- 如果条件能够一一例举出来时,使用switch语句更为简洁
- 如果条件是一个范围时,只能使用if语句,如大于100
- switch语句可以改写为if语句,if语句不一定能改为switch语句
循环
while语句
while(循环条件){//小括号中的条件结果为boolean值
满足循环条件时重复执行的代码
}
do-while语句
do{
满足循环条件时重复执行的代码
}while(循环条件);
注意点
- do-while循环至少执行一次
while语句 VS do-while语句
while循环可以一次都不执行,但do-while循环至少会执行一次。
for语句
//表达式1为定义循环变量
//表达式2为判断循环条件
//表达式3为更新循环变量
for(表达式1;表达式2;表达式3){
循环体
}
for循环特殊情况
-
可以使用外部定义的循环变量
int i = 0; for (;i<=10;i += 2) { System.out.println(i); }
-
可以在循环体重更新循环变量
int i = 0; for (;i<=10;) { System.out.println(i); i += 2; }
循环控制
停止循环(break 和 return)
- 所有的循环都可以使用break和return停止循环。
- break是停止循环后,继续执行循环之外的内容。
- return是结束方法,不再执行return之后的内容
int i = 1; while (true) {//死循环 System.out.println("xxxxx"); if (i++ == 10) { break;//退出整个循环,程序继续执行循环之外的内容 // return;//退出整个方法,程序不再执行之后的代码 } } System.out.println("结束");//如果循环中有return,不会执行这句话
停止本次循环(continue)
- 在循环语句中,使用continue,可以停止本次循环,不再执行continue之后的代码,直接进行下一次循环。
int i = 1; while (i < 10) { if (i++ % 2 == 0) { continue;//如果遇到continue,结束本次循环(不再执行continue之后的代码),直接进入下一 次循环 } S ystem.out.println(i); } / /最终打印2 4 6 8 10
while语句 VS do-while语句 VS for语句
- 如果已知循环次数,推荐使用for循环。如遍历数组、集合等。
- 如果未知循环次数,推荐使用while循环。
- while循环和for循环可以相互转换
- do-while循环至少执行一次,for循环和while循环有可能一次都不执行
循环嵌套
使用场景
如果一个重复的过程还需要将其整体重复执行时,可以使用循环嵌套。
数组
概念
一组类型相同的数据的有序集合。
注意点
-
实际在内存中是一块连续的空间。是保存数据的区域。
-
数组定义时需要确定大小和数据类型,不可改变。
-
定义数组时的变量保存的是实际内存空间的地址。
-
数据中保存的数据称为元素,每个元素有一个唯一的位置,称为索引(下标),这个索引从0计数。
-
可以通过数组的索引给数组赋值或读取数组中某个索引上的值。
定义数组
语法1:数据类型[] 数组名(建议使用)
int[] arr;
语法2:数据类型 数组名[]
int arr[];
注意点
- 定义数组后,如果不初始化数组,数组无法使用。
初始化数组
语法:数组名=new 数据类型[数组大小];
int[] arr;//定义数组(必须定义才能初始化)
arr = new arr[3];
定义和初始化同时进行
语法:数据类型[] 数组名 = new 数据类型[数组大小];
int[] arr = new int[3];
数组赋值
动态赋值
语法:数组名[索引] = 值
int[] arr = new int[5];
arr[0]=999;//索引从0开始
arr[4]=888;//索引最大值为长度-1,超出会抛出数组越界异常
静态赋值
- 语法1:数据类型 [] 数组名 = new 数据类型[]{元素1,元素2,...}
int[] arr = new int[]{1,3,5,7};
- 语法2:数据类型 [] 数组名 = {元素1,元素2,...}
int[] arr = {2,4,6,8}
注意点
- 数组一旦初始化后,数组大小不能改变,其中的元素类型要统一。
- 数组的索引范围是[0,数组大小-1],使用时不能超出范围。在编译时无法识别是否超出数组索引,但运行时会抛出"数组索引溢出"异常。
- 数组一旦初始化后,如果没有赋值,默认有初始值。
数组数据类型 默认值 整型 0 浮点 0.0 布尔型 false 字符型 空白字符 引用类型(如String等) null 读取数组中的元素
- 方法一:数组名[索引](操作单个元素)
String[] nameList={"王海","刘涛","赵敏"}; System.out.println(nameList[1]); System.out.println(nameList[2]);
- 方法二:通过循环给数组赋值和读取元素(操作对个元素)
//定义一个数组保存同学的姓名,循环接收后打印所有。 Scanner sc = new Scanner(System.in); //定义数组 String[] stuName = new String[3]; //循环赋值 for (int i = 0; i < 3; i++) { System.out.println("请输入第"+(i+1)+"位同学的姓名"); stuName[i] = sc.next(); } //循环读取 System.out.println("当前学生列表"); for (int i = 0; i < stuName.length; i++) {//通过“数组名.length”获取数组的长度 System.out.print(stuName[i]+"\t"); }
- 方法三:增强for循环(操作多个元素,只能读取)
//定义一个数组保存同学的姓名,循环接收后打印所有。 Scanner sc = new Scanner(System.in); //定义数组 String[] stuName = new String[3]; //循环赋值 for (int i = 0; i < 3; i++) { System.out.println("请输入第"+(i+1)+"位同学的姓名"); stuName[i] = sc.next(); } //增强for循环 for(数据类型 变量名 : 数组或集合){} for (String name : stuName) { System.out.print(name + "\t"); } System.out.println();
重要排序算法
冒泡排序
数组中每相邻的两个元素进行比较,如果不满足排序的规则,交换位置。
例子:排序 9 7 5 2 1
每轮比较结果 每轮比较的两个数 第一轮比较:7 5 2 1 9
第二轮比较:5 2 1 7 9
第三轮比较:2 1 5 7 9
第四轮比较:1 2 5 7 9比较了4次 97 95 92 91
比较了3次 75 72 71
比较了2次 52 51
比较了1次 21
核心代码
//外层循环控制比较的轮数
for(int i=1;i<=数组.length-1;i++){
//内层循环控制每轮比较的次数
for(int j=1;j<=数组.length-i;j++){
//判断是否要交换位置
if(数组[j-1] < 数组[j]){//如果不满足降序的条件(小于)则交换位置
//借助第三个变量交换数组中元素的位置
int temp = 数组[j];
数组[j]=数组[j-1];
数组[j-1]=temp;
}
}
}
数组工具类Arrays
常用方法 | 作用 |
---|---|
sort(数组) | 将输入中的元素升序排序。 |
sort(数组,起始位置,结束位置) | 对数组中[起始位置,结束位置]区间的元素进行填充。 |
f]ill(数组) | 使用指定值对数组中的所有元素进行填充。 |
fill(数组,起始位置,结束位置) | 使用指定值对数组中[起始位置,结束位置]区间的元素进行填充。 |
copyOf(数组,新数组长度) | 复制数组并指定复制后的数组的长度。得到复制后的新数组。 |
asList(一组数据) | 将一组数据转换为List集合。 |
equals(数组1,数组2) | 判断两个数组是否相同,得到判断的布尔值。只有两个数组一模一样时获得true。 |
本阶段个人心得
在以前大学的课程学过许多门程序语言,所以在有一定的程序语言的基础后,再来系统且细致的学习Java语言,感触颇多。明白在每个基础点,以前可能不是很注意的点,很可能就是容易出错的点。还有一方面是,自身有一定的前端基础且学得不错,所以对于后端知识以前学习就不太够,以至于在编程开发方面没有一个大致的范围的概念。最重要的一点还是不要心浮气躁,枯燥是代码,但有趣的是思维,不做没有感情的敲代码工具,编程开发的学习讲究的是扎实的基础和丰富的实践开发能力,不断坚持完成每天的小目标。拨开雾霾,终见阳光!加油!加油!加油!