注释
注释是解释说明程序的问题,方便自己和别人阅读代码
1.单行注释:
//后面根解释文字
2.多行注释
/*
这里写注释文字
可以写多行
*/
3.文档注释
/**
这里写文档注释
也可以写多行,文档注释可以利用JDK的工具生成帮助文档
*/
字面量
字面量是告诉程序员数据在程序中的书写格式
变量
变量是用来记录程序中的数据的。其本质上是内存中的一块区域,你可以把这块区域理解成一个小盒子。
-
变量的定义格式:
数据类型 变量名 = 初始值;
-
变量记录的数据程序运行过程中是可以发生改变的:
变量名 = 值;
为什么要用变量
//1.假设4多个地方用到整数10; 现在我想把10改为20,这时你得一条语句一条语句的修改
System.out.println(10);
System.out.println(10);
System.out.println(10);
System.out.println(10);
//2.同样这里还是在多个地方用到整数10,你可以先用一个变量记录这个整数10
int x = 10;
//然后在需要用到整数10的地方,用x代替就行;
//如果我们把x值改了,那么后面用到x的值的地方就都一起改变了
System.out.println(x);
System.out.println(x);
System.out.println(x);
System.out.println(x);
变量有应用场景
变量的应用场景无处不在,只要是程序中能发生变化的数据,都可以用变量存储。
变量的注意事项
1.变量定义在哪个{}范围内,就只在哪个大括号内有效。变量的有效范围称之为变量的作用域
{
int a = 10;
System.out.println(a); //这是是对的
}
System.out.println(a); //这里会出错
2.在同一个作用域内,不能有两个同名的变量
{
int a = 10;
int a = 20; //这里会出错
}
3.变量没有初始化只,不能直接使用
int a; //仅仅定义了变量,但是没有初始值
System.out.println(a); //这里会出错
4.变量可以定义在同一行
如:int a=10, b=20; //a和b都是int类型
关键字
关键字是java语言中有特殊含义的单词。比如用int表示整数,用double表示小数等
abstract | assert | boolean | break | byte |
---|---|---|---|---|
case | catch | char | class | const |
continue | default | do | double | else |
enum | extends | final | finally | float |
for | goto | if | implements | import |
instanceof | int | interface | long | native |
new | package | private | protected | public |
return | strictfp | short | static | super |
switch | synchronized | this | throw | throws |
transient | try | void | volatile | while |
关键字的特点:
1.关键字都是小写的
2.关键字在idea中有特殊颜色标记(如果你没有修改关键字的颜色,默认是蓝色的)
标志符
标志符其实就是我们自己取的名字。像前面我们取的类名,变量名其实都是标志符。
强制要求:必须遵守,不遵守就会报错
1.最好是字母、数字、下划线、$组成
2.不能以数字开头
3.不能是Java的关键字
建议遵守:按照下面的方式取名字会显得更加专业
1.所有的名字要见名知意,便于自己和别人阅读
举例: class Student{} //一看这个类就知道表示一个学生
int age =10; //一看这个变量就知道表示年龄
2.类名:首字母大写(大驼峰命名)
举例: class Student{}
3.变量名:第二个单词开始首字母大写(小驼峰命名)
举例: double money = 6.88;
double applePrice = 7.5;
数据类型
Java的数据类型整体上来说分为两大类: 基本数据类型、引用数据类型。
基本数据类型
基本数据类型一共有4类8种,每一种数据类型占用的内存空间不一样,能够表示的数据范围也不一样。
注意:
整型:随便写一个整型字面量,默认是int类型的,73642422442424虽然没有超过long的范围,但是它超过了本身int的范围了。
浮点型:随便写一个小数字面量,默认当成double类型对待的,如果希望这个小数是float类型的,需要在后面加上:F/f。引用数据类型:String.
引用数据类型:String代表的是字符串类型,定义的变量可以用来记住字符串。
long number4 = 73642422442424L;
float score1 = 99.5F;
引用数据类型:String.
// String代表的是字符串类型,定义的变量可以用来记住字符串。
自动类型转换
自动类型转换指的是,数据范围小的变量可以直接赋值给数据范围大的变量,自动类型转换其本质就是在较小数据类型数据前面,补了若干个字节。
byte a = 12;
int b = a; // 发生了自动类型转换了
System.out.println(a);
System.out.println(b);
int c = 100; // 4
double d = c;// 8 发生了自动类型转换了
System.out.println(d);
char ch = 'a'; // 'a' 97 => 00000000 01100001
int i = ch; // 发生了自动类型转换了 => 00000000 00000000 00000000 01100001
System.out.println(i);
自动类型转换还有另外一种形式,就是表达式的自动类型转换。所谓表达式指的是几个变量或者几个数据一起参与运算的式子。需要遵守下面的两条运算规则:
1.多种数据类型参与运算,其结果以大的数据类型为准
2.byte,short,char 三种类型数据在和其他类型数据运算时,都会转换为int类型再运算
注意:即使两个byte运算,结果也会提升为int
强制类型转换
强行将范围大的数据,赋值给范围小的变量,下面是强制类型转换的格式
目标数据类型 变量名 = (目标数据类型)被转换的数据;
强制类型转换的原理,其实就是强行把前面几个字节砍掉,但是有数据丢失的风险。
注意:因为数据范围大的数据,赋值给数据范围小的变量,它有可能装不下;就像把一个大桶的水倒入一个小桶中,有溢出的风险。
int a = 20;
// ALT + ENTER 强制类型转换。
byte b = (byte) a;
System.out.println(a);
System.out.println(b);
int i = 1500;
byte j = (byte) i;
System.out.println(j);
double d = 99.5;
int m = (int) d; // 强制类型转换
System.out.println(m); // 丢掉小数部分,保留整数部分
运算符
运算符就是参与运算的符号。Java提供的运算符有很多种,可以分为算术下面几种
算术运算符
算术运算符有 + - * / %
,其中*
表示乘法,/
表示除法,%
表示取余数
/: 两个整数相除,结果也是一个整数
%: 表示两个数相除,取余数
注意的是:+
符号除了用于加法运算,还可以作为连接符。+
符号与字符串运算的时候是用作连接符的,其结果依然是一个字符串。
自增自减运算符
++
读作自增,--
读作自减;
注意的是:自增自减只能操作变量不能操作字面量的,会报错!自增自减只能对变量进行操作,不能操作字面量。具体使用时也分为两种情况,如下:
1.单独使用:++或者--放在变量前面没有区别
2.混合使用:++或者--放在变量或者前面运算规则稍有不同
//++在后:先做其他事情,再做自增和自减
int a = 10;
int b = a++; //等价于 int b = a; a++;
//++在前:先自增或者自减,再做其他运输
int x = 10;
int y = --x; //等价于x--; int y = x;
赋值运算符
基本的赋值运算符其实就是=
号,意思就是把右边的数据赋值给左边的变量。
int a = 10; //将数据10赋值给左边的变量a
扩展的赋值运算符
以+=
为例来看一下它的运算规则,其他的运算符运算同理
int a = 10;
//+=解析:在a原来记录值10的基础上累加5,将结果重新赋值给a;
a+=5;
//最终打印a的值为15
System.out.println(a);
byte x = 10;
byte y = 30;
x = x + y;
x+=3;
其中:x = x + y; 这句代码有问题,因为两个byte类型数据相加,会提升为int类型;
x+=3; 这句代码没有问题,因为这里有隐含的强制类型转换,等价于 byte x = (byte)(x+y);
关系运算符
关系运算符在程序中常用于条件判断,根据条件判断的结果是true还是false,来决定后续该执行哪些操作。
逻辑运算符
逻辑运算符是用来将多个条件放在一起运算,最终结果是true或者false
我们通过几个案例来演示一下逻辑运算符的使用
// 需求:要求手机必须满足尺寸大于等于6.95,且内存必须大于等于8.
double size = 6.8;
int storage = 16;
// 1、& 前后的条件的结果必须都是true ,结果才是true.
boolean rs = size >= 6.95 & storage >= 8;
System.out.println(rs);
// 需求2:要求手机要么满足尺寸大于等于6.95,要么内存必须大于等于8.
// 2、| 只要多个条件中有一个是true,结果就是true.
boolean rs2 = size >= 6.95 | storage >= 8;
System.out.println(rs2);
// 3、!取反的意思
System.out.println(!true); // false
System.out.println(!false); // true
System.out.println(!(2 > 1)); // false
// 4、^ 前后条件的结果相同时返回false,不同时返回true.
System.out.println(true ^ true); // false
System.out.println(false ^ false); // false
System.out.println(true ^ false); // true
System.out.println(false ^ true); // true
// 5、&& 左边为false,右边不执行。
int i = 10;
int j = 20;
// System.out.println(i > 100 && ++j > 99);
System.out.println(i > 100 & ++j > 99);
System.out.println(j);
// 6、|| 左边是true ,右边就不执行。
int m = 10;
int n = 30;
// System.out.println(m > 3 || ++n > 40);
System.out.println(m > 3 | ++n > 40);
System.out.println(n);
注意:逻辑运算符在程序中常用于组合几个条件判断,根据条件判断的结果是true还是false,来决定后续该执行哪些操作。
1、& 前后的条件的结果必须都是true ,结果才是true.
2、| 只要多个条件中有一个是true,结果就是true.
3、!取反的意思。
4、^ 前后条件的结果相同时返回false,不同时返回true.
5、&& 左边为false,右边不执行。
6、|| 左边是true ,右边就不执行
三元运算符
三元运算的执行流程:首先计算关系表达式的值,如果关系表达式的值为true,则返回值1;如果关系表达式的值为false, 则返回值2;
关系表达式? 值1 : 值2;
运算优先级
如果你想要知道各个运算符的优先级,哪些先算哪些后算,可以参考下面这张图
从图中我们发现,&&运算比||运算的优先级高,所以&&和||同时存在时,是先算&&再算||;
在实际开发中,其实我们很少考虑运算优先级, 因为如果你想让某些数据先运算,其实加()
就可以了 。
程序流程控制
程序流程控制就是控制程序的执行顺序。程序的流程控制一般分为3种:顺序结构、分支结构、循环结构。
-
顺序结构:就是不加任何控制,代码从main方法开始自上而下执行
-
分支结构:就是根据条件判断是true还是false,有选择性的执行哪些代码。在Java语言中提供了两个格式if 、 switch
-
循环结构:就是控制某一段代码重复执行。在Java语言中提供了三种格式,for、while、do-while
分支结构
if分支
if它的作用,是用于对条件进行判断,判断的结果只可能有两个值true或者false,然后根据条件判断的结果来决定执行那段代码。
if 第一种形式执行流程如下:
如果 条件表达式 为true,就执行下面的语句体
如果 条件表达式 为false,就不执行
if 第二种形式执行流程如下:
如果 条件表达式 为true,就执行下面的语句体1
如果 条件表达式 为false,就执行else下面的语句体2
if 第三种形式执行流程如下:
如果 条件表达式1 为true,就执行下面的代码1;
如果 条件表达式1 为false,就继续判断条件表达式2;如果 条件表达式2 为true,就执行下面的语句体;
如果 条件表达式2 为false,就继续判断条件语句体3;如果 条件表达式3 为true,就执行下面的语句体3
如果 条件表达式3 为false,就继续判断后面的表达式;....
如果前面所有条件表达式判断都为false,就执行最后的else语句中的代码
使用技巧:if后面的大括号,如果只有一行代码,大括号可以省略
switch分支
switch 分支的作用,是通过比较值来决定执行哪条分支代码。
case穿透现象:当switch语句中没有遇到break,就会直接穿透到下一个case语句执行,直到遇到break为止。这种语法设计也是有它的用处的,当多个case语句想要执行同一段代码时,可以利用case穿透现象,提高代码复用性。
注意事项:
- 1.表达式类型只能是byte、short、int、char
JDK5开始支持枚举,JDK7开始支持String
不支持double、float、double
- 2.case给出的值不允许重复,且只能是字面量,不能是变量。
- 3.正常使用switch的时候,不要忘记写break,否则会出现穿透现象。
if 、switch如何选择
如果单从功能上来讲,if 分支 的功能是更加强大的,switch分支能做的事情if 分支都能做。但是具体用哪一种分支形式,也是有一些使用原则的。
- 如果是对一个范围进行判断,建议使用if分支结构
- 如果是与一个一个的值比较的时候,建议使用switch分支结构
循环结构
循环结构可以控制一段代码重复执行。循环结构有for循环、while循环、do-while循环。
for循环
//for循环格式:
for (初始化语句; 循环条件; 迭代语句) {
循环体语句(重复执行的代码);
}
初始化语句:一般是定义一个变量,并给初始值
循环条件:一般是一个关系表达式,结果必须是true或者false
迭代语句:用于对条件进行控制,一般是自增或者自减
循环语句体:需要重复执行的代码
for循环应用场景:其实只要是重复做的事情,都可以用循环语句来做
while循环
for、while如何选择
while循环和for循环的执行流程是一样的。
-
从功能来说:能够用for循环做的,都能用while循环做。
-
使用规范上来说:知道循环几次,建议使用for;不知道循环几次建议使用while
do-while循环
三种循环的区别
1. for循环 和 while循环(先判断后执行);
do...while (先执行后判断)
2.for循环和while循环的执行流程是一模一样的,
功能上无区别,for能做的while也能做,反之亦然。
如果已知循环次数建议使用for循环,如果不清楚要循环多少次建议使用while循环。
3.for循环中控制循环的变量只在循环中使用
while循环中,控制循环的变量在循环后还可以继续使用
死循环
死循环就是停不下来的循环。
//for死循环
for ( ; ; ){
System.out.println("Hello World1");
}
//while死循环
while (true) {
System.out.println("Hello World2");
}
//do-while死循环
do {
System.out.println("Hello World3");
}while (true);
死循环应用场景:最典型的是可以用死循环来做服务器程序, 比如百度的服务器程序就是一直在执行的,你随时都可以通过浏览器去访问百度。
循环嵌套
循环嵌套,就是一个循环中又包含另一个循环
循环嵌套执行流程:外部循环每循环一次,内部循环会全部执行完一轮。
跳转语句 break 、continue
-
break作用:跳出并结束当前所在循环的执行
-
continue作用:结束本次循环,进入下一次循环
Java数组
数组就是一个容器,用来存一批同种类型的数据的。
int[] array = {20,10,80,60,90};
String[] names = {"牛二", "西门", "全蛋"};
遇到批量数据的存储和操作时,数组比变量更适合
数组的定义和访问
数组有两种初始化的方式,一种是静态初始化、一种是动态初始化。
数组的静态初始化
静态初始化标准格式:数据类型[] 变量名 = new 数据类型[]{元素1,元素2,元素3};
int[] ages = new int[]{12, 24, 36}
静态初始化提供了一种简化写法:数据类型[] 变量名 = {元素1,元素2,元素3};
int[] ages = {12, 24, 36}
数组的元素访问:数组名[索引]
int[] arr = {12, 24, 36};
System.out.println(arr[0]); //12
修改数组中的数据
int[] arr = {12, 24, 36};
arr[0] = 66;
System.out.println(arr[0]); //66
数组的长度
int[] arr = {12, 24, 36};
System.out.println(arr.length);
数组的遍历
遍历意思就是将数组中的元素一个一个的取出来。可以使用for循环从0开始一直遍历到长度-1的位置,就可以获取所有的索引了。
int[] ages = {12, 24, 36};
for (int i = 0; i < ages.length; i++) {
// i的取值 = 0,1,2
System.out.println(ages[i]);
}
数组的动态初始化
动态初始化不需要我们写出具体的元素,而是指定元素类型和长度就行。
//数据类型[] 数组名 = new 数据类型[长度];
int[] arr = new int[3];
数组的执行原理
多个变量指向同一个数组
-
两个变量指向同一个数组时,两个变量记录的是同一个地址值。
-
当一个变量修改数组中的元素时,另一个变量去访问数组中的元素,元素已经被修改过了。
数组求最大值
数组求最大值思路: 1)先找出数组中0索引的元素,假设为最大值,用max表示2)遍历后面的每一个元素和max比较,把较大的元素值重新赋值给max3)最后max就是所有元素的最大值
int[] faceScores = {15, 9000, 10000, 20000, 9500, -5};
// 定义一个变量用于最终记住最大值。
int max = faceScores[0];
// 从数组的第2个位置开始遍历。
for (int i = 1; i < faceScores.length; i++) {
// i = 1 2 3 4 5
// 判断一下当前遍历的这个数据,是否大于最大值变量max存储的数据,
//如果大于,当前遍历的数据需要赋值给max
if(faceScores[i] > max ){
max = faceScores[i];
}
}
System.out.println("max:" + max);
数组元素反转
数组元素反转的核心,其实是数组中两个数据的交换。数组中元素交换,就是用的借用第三方变量的思想。 我们把数组中的每一个元素当做一个水杯,然后索引控制哪两个元素互换位置。我们只需将第一个和最后一个元素互换、第二个和倒数第二个互换、依次内推....
1.每次交换,需要有左右两边的两个索引,我们可以用i和j表示
刚开始i=0,j=数组长度-1;
2.每次让i和j索引位置的两个元素互换位置
arr[i]和arr[j]互换位置
3.每次还完位置之后,让i往右移动一位,让j往前移动一位
int[] arr = {10, 20, 30, 40, 50};
// 定义一个循环,设计2个变量,一个在前,一个在后
for (int i = 0, j = arr.length - 1; i < j; i++, j--) {
// arr[i] arr[j]
// 交换
// 1、定义一个临时变量记住后一个位置处的值
int temp = arr[j];
// 2、把前一个位置处的值赋值给后一个位置了
arr[j] = arr[i];
// 3、把临时变量中记住的后一个位置处的值赋值给前一个位置处
arr[i] = temp;
}