目录
Java概述
- Java语言是美国Sun公司(Stanford University Network)在1995年推出的计算机语言。
- Java之父:詹姆斯·高斯林(James Gosling)。
- 2009年,Sun公司被甲骨文公司收购 。
Java语言跨平台
- Java程序并非是直接运行的,Java编译器将Java源程序编译成与平台无关的字节码文件(class文件),然后由Java虚拟机(JVM)对字节码文件解释执行。所以在不同的操作系统下,只需安装不同的Java虚拟机即可实现java程序的跨平台。
JRE和JDK
- JVM(Java Virtual Machine),Java虚拟机。
- JRE(Java Runtime Environment),Java运行环境,包含了JVM和Java的核心类库(Java API)。
- JDK(Java Development Kit)称为Java开发工具,包含了JRE和开发工具总结:我们只需安装JDK即可,它包含了 java的运行环境和虚拟机。
Java基础语法
注释
- 注释是对代码的解释和说明文字,可以提高程序的可读性,因此在程序中添加必要的注释文字十分重要。Java中的注释分为三种:
单行注释:单行注释的格式是使用//,从//开始至本行结尾的文字将作为注释文字。
public class day04 {
public static void main(String[] args) {
//这是单行注释的内容
}
}
多行注释:多行注释的格式是使用 /* 和 */ 将一段较长的注释括起来。(注意:多行注释不能嵌套使用)
public class day04{
public static void main(String[] args){
/*这是多行注释文字这是多行注释
文字这是多行注释文字
*/
}
}
文档注释:文档注释以 /** 开始,以 */ 结束。(常用在写类、方法中)(以后讲)
字面量
- 告诉程序员,数据在程序中的格式
字面量分类 | 生后中的写法 | 程序中的写法 | 说明 |
整数 | 666,-88 | 666,-88 | 程序中跟生活中写法一致 |
小数 | 13.14,-5.21 | 13.14,-5.21 | 程序中跟生活中写法一致 |
字符 | A,0,我 | 'A','0','我' | 程序中必须使用单引号,有且仅能一个字符 |
字符串 | Java你好 | "Java你好" | 程序中必须使用双引号,内容可有可无 |
布尔值 | true,false | true,false | 布尔值,表示真假,只有两个值:true、false |
空值 | 值是:null | 一个特殊的值,空值(后面会讲解,暂时不用) |
数据类型分类
- 引用数据类型(除基本数据类型之外,如String其他的后面学习)
- 基本数据类型:4大类8种
关键字 | 取值范围 |
byte | -128~127 |
Short | -32768~32767 |
int(默认) | -2147483648~2147483647(10位数) |
Long | -9223372036854775808~9223372036854775807(19位数) |
Double | 1.401298e-45到3.402823e+38 |
false | 4.9000000e 到 1.797693e+308 |
char | 0-65535 |
boolean | true、false |
类型转换
自动类型转换
什么是自动类型转换
类型范围小的变量,可以直接赋值给类型范围大的变量
public class day04{
public static void main(String[] args){
byte a =12;
int b =a;
System.out.println(b);//12
}
}
自动转换类型转换的图形
byte ---- short ----- char ----- int(默认)------ long float ---double
为什么要进行类型转换
存在不同类型的变量赋值给其他类型的变量
表达式的自动类型转换
在表达式中、小范围类型的变量会自动转换当前[int]较大范围的类型再运算
byte ----- short ---- char ---- int ---- long ----float ---double
注意事项:
表达式的最终结果类型由表达式中的最高类型决定
在表达式中,byte,short,char是直接转换成int类型参与运算的
强制类型转换
什么是强制转换类型
可以强行将类型范围大的变量、数据赋值给类型范围小的变量
public class day04{
public static void main(String[] args){
//数据类型 变量 =(数据类型)变量、数据
int a =20;
byte b =(byte)a;
System.out.println(b);//20
}
}
问题:
类型范围大的数据或变量,不能直接赋值给类型范围小的变量,会报错
注意事项:
可能出现数据丢失
小数强制转换成整数是直接截断雄小数保留整数
运算符
运算符:对字面量或者变量进行操作的符号
算术运算符
符号 | 作用 | 说明 |
+ | 加 | |
- | 减 | |
* | 乘 | |
/ | 除 | |
% | 取余(模) | 获取的是两个数据做除法的余数 |
注意:
如果两个整数做除法,其结果一定是整数,因为最高类型是整数
自增自减运算符
符号 | 作用 | 说明 |
++ | 自增 | 变量自身的值加1 |
-- | 自减 | 变量自身的值减1 |
注意:
++ 和 -- 既可以放在变量的后面,也可以放在变量的前边。
++ 、 -- 只能操作变量,不能操作字面量的。
自增、自减运算符在变量前后的区别
如果单独使用放前后是没有区别的
非单独使用:在变量前,先进行变量自增、自减,再使用变量
非单独使用:在变量后,先使用变量,再进行变量自增、自减
赋值运算符
符号 | 作用 | 说明 |
+= | 加后赋值 | a+=b等价于a = (a的数据类型)(a+b); 将a + b的值给a |
-= | 减后赋值 | a-=b等价于a = (a的数据类型)(a-b); 将a - b的值给a |
*= | 乘后赋值 | a=b等价于a = (a的数据类型)(ab); 将a * b的值给a |
/= | 除后赋值 | a/=b等价于a = (a的数据类型)(a/b); 将a / b的值给a |
%= | 取余后赋值 | a%=b等价于a = (a的数据类型)(a%b); 将a % b的值给a |
注意:扩展的赋值运算符隐含了强制类型转换
关系运算符
是对数据进行条件判断的符号,最终会返回一个比较的布尔结果(true,false)
符号 | 说明 |
== | a==b,判断a和b的值是否相等,成立为true,不成立为false |
!= | a!=b,判断a和b的值是否不相等,成立为true,不成立为false |
> | a>b,判断a和b的值是否大于b,成立为true,不成立为false |
>= | a>=b,判断a和b的值是否大于等于b,成立为true,不成立为false |
< | a<b,判断a和b的值是否小于b,成立为true,不成立为false |
<= | a<=b,判断a和b的值是否小于等于b,成立为true,不成立为false |
逻辑运算符
可以把多个条件的布尔结果放在一起运算,最终返回一个布尔结果
符号 | 介绍 | 说明 |
& | 逻辑与 | 必须都是true,结果才是true;只要有一个false,结果一定为false |
| | 逻辑或 | 只要有一个为true、结果就是true |
! | 逻辑非 | 你真我假、你假我真。!true=false 、 !false=true |
^ | 逻辑异或 | 如果两个条件都是false或者都是true则结果是false。两个条件不同结果是true |
短路逻辑运算符
符号 | 介绍 | 说明 |
&& | 短路与 | 判断结果为 ‘&’ 一样。左边为false,右边则不执行 |
|| | 短路或 | 判断结果为 ‘|’ 一样。左边为true,右边则不执行 |
注意:
逻辑与 “&” 、逻辑或 “|”:无论左边是false 还是true,右边都会执行
逻辑运算符特点
逻辑与“&”:有一个为false、结果是false
逻辑异或“^”:相同是false、不同是true。
逻辑非“!”:!false=true、!true=false
短路或||:一个为true、结果是true。前一个为true,后一个条件不执行了
逻辑或“|”:有一个为true、结果是true
短路与&&:一个为false、结果是false。前一个为false,后一个条件不执行了
注意:实际开发中、常用的逻辑运算符还是:&&、|| 、!
三元运算符
格式:条件表达式 ? 值1 : 值2;
执行流程:首先计算关系表达式的值,如果值为true,返回值1,如果为false,返回值2。
运算符优先级
在表达式中,哪个运算符先执行后执行是要看优先级的
优先级 | 运算符 |
1 | () |
2 | !、-、++、-- |
3 | *、/、% |
4 | +、- |
5 | >、>>> |
6 | 、>=、instanceof |
7 | ==、!= |
8 | & |
9 | ^ |
10 | | |
11 | && |
12 | || |
13 | ?: |
14 | =、+=、-=、*=、/=、%=、&= |
流程控制
if分支
public class day04{
public static void main(String[] args){
第一种格式:
if(条件){
语句体;
}
//执行流程:首先判断条件表达式的结果,如果为true执行语句体,为false就不执行语句体。
第二种格式:
if(条件){
语句体1;
}else{
语句体2;
}
//执行流程:首先判断条件表达式的结果,如果为true执行语句体1,为false执行语句体2。
第三种格式:
if(条件1){
语句体1;
}else if(条件2){
语句2;
}else if(条件3){
语句3;
}else{
语句4;
}
/*执行流程:
1、先**判断条件1**的值,如果为true执行语句体1,分支结束;如果为false则**判断
条件2**的值
2、如果值为true就执行语句体2,分支结束;如果为false则**判断条件3**的值
3、如果**没有任何条件为true**,就执行else分支的语句体语句4
*/
}
}
switch分支
public class day04{
public static void main(String[] args){
格式:
switch(表达式){
case 值1:
执行代码...;
break;
case 值2:
执行代码...;
break;
default:
执行代码...;
}
/*执行流程:
1、先执行表达式的值,拿着这个值去与case后的值进行匹配。
2、匹配哪个case的值为true就执行哪个case,遇到break就跳出switch语句分
支。
3、如果case后的值不匹配则执行default代码。
*/
}
}
switch注意事项
- 表达式类型只能是byte、short、int、char、 不支持long、float、double
- case给出的值不允许重复,且只能是字面量,不能是变量
- 不要忘记写break,否则会出现穿透现象
循环结构
for循环
public class day04{
public static void main(String[] args){
格式:
for(初始化语句;循环条件;送代语句){
循环体语句(重复执行的代码)
}
示例:输出3次HelloWord
for(int i =0; i < 3; i++(可改:i+=2)){
System.out.println("HelloWord");
}
/*执行的流程:
1、循环一开始,执行int i = 0 一次。
2、然后判断循环条件:0 < 3返回true ,进入到循环体中执行输出:helloWorld ,然后执行迭代语句i++ , 此时i=1了。
3、然后判断循环条件:1 < 3返回true ,进入到循环体中执行输出:helloWorld ,然后执行迭代语句i++ , 此时i=2了。
4、然后判断循环条件:2 < 3返回true ,进入到循环体中执行输出:helloWorld,然后执行迭代语句i++ , 此时i=3了。
5、然后判断循环条件:3< 3返回false, 循环立即结束!!
*/
}
}
while循环
public class day04{
public static void main(String[] args){
格式:
初始化语句:
while(循环条件){
循环体语句(被重复执行的代码)
送代语句;
}
示例:
int i =0;
while(i<3){
System.out.println("HelloWrod");
i++;
}
}
}
什么时候用for循环,什么时候用while循环
- 功能上是完全一样的,for循环解决的whlie也能解决
- 使用规范是:知道循环几次:使用for循环;不知道循环几次使用:while(使用while比较专业一些)
do....while循环
- 先执行再判断循环条件
public class day04{
public static void main(String[] args){
格式:
初始化语句;
do{
循环体语句;
送代语句;
}while(循环条件);
示例:
int i =0;
do{
System.out.println("HelloWord");
i++;
}while(i<3);
}
}
三种循环的区别
for循环和 while循环(先判断后执行)
do....while循环(第一次先执行后判断)
死循环 与 嵌套循环
- 死循环
public class day04{
public static void main(String[] args){
for循环的格式:
for(;;){
System.out.println("HelloWord");
}
while循环的格式:
while(true){
System.out.println("HelloWord");
}
do.....while循环的格式:
do{
System.out.println("HelloWord");
}while(true);
}
}
- 嵌套循环
- 循环中包含循环 特点:外部循环每循环一次,内部循环全部执行行完一次
public class day04{
public static void main(String[] args){
//外循环代表行
for(int i =0; i<5;i++){
//内循环代表列
for(int j =0;j<5;j++){
System.out.print("*");
}
System.out.println();//换行
}
输出结果:
*****
*****
*****
*****
*****
}
}
break、continue关键字
- break : 跳出并结束当前所在循环的执行
- continue : 用于跳出当前循环的当次执行,进行下一次循环
注意事项:
break:只能用于结束所在循环,或者结束所在switch分支的执行
continue:只能在循环中进行使用
break和continue扩展知识
break:可以用在嵌套循环中跳出整个外部循环的并立即结束它。
public class day04{
public static void main(String[] args){
OUT:
for(int i =0;i<4;i++){
for(int j =0;j<5;j++){
break OUT;
}
}
}
}
continue:可以用在嵌套循环中跳出外部循环的当次执行,进入外部循环的下一次
public class day04{
public static void main(String[] args){
OUT:
for(int j =0;j<5;j++){
for(int j =0;j<5;j++){
continue OUT;
}
}
}
}
Random随机数
Random随机数如何生成 65 — 91之间的随机数
65 - 91 =》(0-26)+65
int number =r.nextInt(27)+65;
数组
- 数组就是用来存储一批同种类型数据的内存区域(容器)
静态初始化
-
定义数组的时候直接给数组赋值(就是知道他的值是多少)
public class day08{
public static void main(String[] args){
数组格式:
//完整版格式
数据类型[] 数组名 =new 数据类型[]{元素1,元素2,元素3};
double[] array =new double[]{89.9 , 90.0 , 99.0};
//简化版格式
数据类型[] 数组名 ={元素1,元素2,元素3};
int[] arr={12,23,44};
}
}
注意:数组变量名中存储的是数组在内存中的地址,数组是(引用数据类型,存储的数组在内存中的地址信息)
数组的访问:
public class day08{
public static void main(String[] args){
//取值
int[] arr={12,22,33}
// 0 ,1, 2
System.out.println(arr[0])//12 称为:数组名称[索引]
}
}
数组的长度属性:length
public class day08{
public static void main(String[] args){
//获取数组的长度(就是数组元素的个数)
System.out.println(arr.length);
//数组最大索引可以表示:数组名.length-1 前提:元素个数要大于0
}
}
动态初始化
- 定义数组的时候只确定元素的类型和数组长度,之后再存入具体数据
public class day08{
public static void main(String[] args){
格式:
数据类型[] 数组名 =new 数据类型[长度];
int[] array =new int[10];
后赋值:
arr[0]=10;
System.out.println(arr[0]);//10
}
}
两者定义区别
- 当前已知道存入的元素,用静态初始化
- 当前还不清楚要存入那些数据,用动态初始化
遍历初始化的使用场景、注意事项:
动态初始化:只指定数组长度,后赋值,适合开始知道数据的数量,但是不确定具体元素值的业务场景。
静态初始化:开始就存入元素值,适合一开始就能确定元素值的业务场景
注意:两种格式的写法是独立的,不可以混用
public class day08{
public static void main(String[] args){
int[] arr =new int[10]{9,3,5,6};//报错
}
}
遍历数组
遍历:就是一个一个对数据访问
public class day08{
public static void main(String[] args){
int[] ages ={20,22,44,8};
for(int i =0;i<ages.length;i++){
System.out.println(ages[i]);
}
}
}
冒泡排序
思想:
从头开始两两比较,把较大的元素较小的元素进行交换
每轮把当前最大的一个元素存入到数组当前的末尾。
步骤:
定义一个外部循环控制总共需要冒几轮(数组的长度-1)
定义一个内部循环,控制每轮依次往后比较几个位置(数组长度-i-1)
如果当前位置的元素值>后一个位置的元素值,两者交换
public class day09{
public static void main(String[] args){
//定义外部循环控制循环总共循环几次
for(int i =0; i<arr.length-1;i++){
//定义一个内循环控制循环比较几次,减i的意思就是把比较过的减去继续循环
for(int j =0;j <arr.length-i-1;j++){
//定义一个if判段是否比后一个数字大
if(arr[j] > arr[j+1]){
//定义一个变量两者交换位置
int tmpe =arr[j];
arr[j] =arr[j+1];
arr[j+1]= tmpe;
}
}
}
//遍历数组输出
System.out.print("排序后:");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
//输出结果
排序后:1,2,3,4,5,6,7,8,9
}
}
方法
方法是一种语法结构,它可以把一段代码封装成一个功能,方便重复调用
提高了代码的复用性
让程序的逻辑更清晰
public static class method{
public static void main(String[] args){
//方法定义格式:
修饰符 返回值类型 方法名(形参列表){
方法体代码(需要执行的功能代码)
return 返回值;
}
//调用方法格式
方法名(.....);
}
}
示例:使用方法对2个整数求和并返回(有返回值类型)
public class method{
// 修饰符 返回值类型 方法名 形参列表
public static int print (int a , int b){
int c =a+b; //方法的执行代码
return c; //返回值
}
public static void main(String[] args){
//调用方法
int sum =print(10,20);
System.out.println(sum);//输出结果:30
}
}
方法格式注意(有返回值类型):
方法的修饰符:暂时都用public static修饰
方法申明了具体的返回值类型,内部必须使用return返回对类型的数据。
形参列表可以有多个,甚至可以没有;如果有多个形参,多个形参必须用 “,”(逗号隔开,且不能给初始化值)
其他方法写法(无返回值类型):
方法定义时:返回值类型、形参列表可以按照需求进行填写
注意事项:
如果方法不需要返回结果,返回值类型必须申明成void(无返回值),
此时方法内部不可以使用return返回数据
方法如果没有参数,或者返回值类型申明为void可以称为无参数、无返回值的方法,依次类推
示例:打印3行Hello World(无返回值)
public class method{
public static void print(){
System.out.println("Hello World");
System.out.println("Hello World");
System.out.println("Hello World");
}
public static void main(String[] args){
System.out.println(print());//调用方法
}
}
常见问题:
方法的编写顺序无所谓。
方法与方法之间是平级关系,不能嵌套定义。
方法的返回值类型为void(无返回值),方法内则不能使用return返回数据,如果方法的返回值类型写了具体类型,方法内 部则必须使用return返回对应类型的数据。
return语句下面,不能编写代码,因为永远执行不到,属于无效的代码。
方法不调用就不执行, 调用时必须严格匹配方法的参数情况。
有返回值的方法调用时可以选择定义变量接收结果,或者直接输出调用,甚至直接调用;无返回值方法的调用只能直接调用