基础语法
注释
概念
注释是在程序指定位置添加的说明信息
分类
- 单行注释://注释信息
- 多行注释:/* 注释信息*/
- 文档注释:/** 注释信息*/
注意事项
注释内容不会参与编译与运行,仅仅是对代码的解释说明。
不管是单行注释还是多行注释,在书写的时候都不要嵌套。
关键字
概念
被Java赋予了特定涵义的英文单词
特点
关键字的字母全部小写
变量
概念
在程序的执行过程中,其值有可能发生改变的量。
格式
数据类型 变量名=数据值;
变量的注意事项
- 只能存一个值
- 变量名不允许重复定义
- 一条语句可以定义多个变量
- 变量在使用之前一定要进行赋值
- 变量的作用域范围
数据类型
基本数据类型
引用数据类型
标识符
概念
就是给类、方法、变量等起的名字。
命名规则
- 由数字、字母、下划线(_)和美元符号($)组成
- 不能以数字开头
- 不能是关键字
- 区分大小写
软性建议:
小驼峰命名法 | 大驼峰命名法 | |
---|---|---|
规则 | 标识符是一个单词的时候,全部小写。标识符由多个单词组成的时候,第一个单词首字母小写,其它单词首字母大写 | 标识符是一个单词的时候,首字母大写。标识符由多个单词组成的时候,每个单词的首字母大写 |
举例 | 方法名、变量名 | 类名 |
运算符
运算符和表达式
概念
- 运算符:对字面量或者变量进行操作的符号
- 表达式:用运算符把字面量或者变量连接起来,符合java语法的式子就可以称为表达式。
运算符
算术运算符
符号 | 作用 |
---|---|
+ | 加 |
_ | 减 |
* | 乘 |
/ | 除 |
% | 取模/取余 |
备注:在代码中,如果有小数参与计算,结果有可能不精确的。
- 隐式转换:
- 取值范围:byte< short< int< long< float< double。
- 数据类型不一样,不能进行运算,需要转成一样的才可以进行计算。
- 取值范围小的,和取值范围大的进行运算,小的会先提升为大的,再进行计算。
- byte、short、char三种类型的数据在运算的时候,会直接先提升为int,然后再进行计算。
- 强制转换:
- 如果把一个取值范围大的数值,赋值给取值范围小的变量。是不允许直接赋值的。如果一定要这么做就需要加入强制转换。
- 字符串的"+"操作
- 当"+"操作中出现字符串时,这个"+"是字符串的连接符,而不是算术运算符了。会将前后的数据进行拼接,并产生一个新的字符串。
- 字符的"+"操作
- 当字符+字符时,字符+数字时,会把字符通过ASCII码表查询到的对应的数字再进行计算。
自增自减运算符
符号 | 作用 | 说明 |
---|---|---|
++ | 加 | 变量的值加1 |
-- | 减 | 变量的值减1 |
- ++和--既可以放在变量的前边,也可以放在变量的后边。
- ++和--无论是放在变量的前边还是后边,单独写一行结果还是一样的。
赋值运算符
符号 | 作用 |
---|---|
= | 赋值 |
+= | 加后赋值 |
-= | 减后赋值 |
* = | 乘后赋值 |
/= | 除后赋值 |
%= | 取余后赋值 |
注意事项:扩展的赋值运算符隐含了强制类型转换
关系运算符
符号 | 说明 |
---|---|
== | 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 |
逻辑运算符
符号 | 作用 | 说明 |
---|---|---|
& | 逻辑与 | 并且,两边都为真,结果才是真 |
\ | 逻辑或 | 或者,两边都为假,结果才是假 |
^. | 逻辑异或 | 相同为false,不同为true |
! | 逻辑非 | 取反 |
短路逻辑运算符
符号 | 作用 | 说明 |
---|---|---|
&& | 短路与 | 结果跟与相同,但是具有短路作用 |
\ \ | 短路或 | 结果跟或相同,但是具有短路作用 |
三元运算符
- 格式:关系表达式?表达式1:表达式2;
- 例子:int a=c>b?10:20;
- 计算规则:
- 首先计算关系表达式的值
- 如果值为true,表达式1的值就是运算结果
- 如果值为false,表达式2的值就是运算结果
运算符的优先级
流程控制语句
顺序结构
顺序结构语句是Java程序默认的执行流程,按照代码的先后顺序从上到下依次执行
分支机构
if语句
if语句1
ini
if (关系表达式){
语句体;
}
if语句2
ini
if (关系表达式) {
语句体1;
} else {
语句体2;
}
graph TD
开始 --> 关系表达式 --> true--> 语句体1 --> 其他语句
关系表达式 --> false--> 语句体2 --> 其他语句
if语句3
ini
if (关系表达式1) {
语句体1;
} else if (关系表达式2) {
语句体2;
} ...
else {
语句体n+1;
}
graph TD
关系表达式1 --> true1 --> 其他语句
关系表达式1 --> false1 --> 关系表达式2
关系表达式2 --> true2 --> 语句体2 -->其他语句
关系表达式2 --> false2 --> 关系表达式n
关系表达式n --> truen --> 语句体n -->其他语句
关系表达式n --> falsen --> 语句体n+1 -->其他语句
switch语句
arduino
switch (表达式) {
case 值1:
语句体1;
break;
case 值2:
语句体2;
break;
...
default:
语句体n+1;
[break;]
}
循环结构
for循环
ini
for (初始化语句;条件语句;条件控制语句) {
循环体语句;
}
while循环
ini
初始化语句;
while (条件判断语句) {
循环体语句;
条件控制语句;
}
for和while的区别
- for循环中,控制循环的变量,因为归属for循环的语法结构中,在for循环结束后,就不能再次被访问到了
- for循环中:知道循环次数或者循环的范围
- while循环中,控制循环的变量,对于while循环来说不归属于其语法结构中,在while循环结束后,该变量还可以继续使用
- while循环:不知道循环的次数和范围,只知道循环的结束条件
do...while循环
ini
初始化语句;
do {
循环体语句;
条件控制语句;
} while (条件判断语句)
跳转控制语句
- continue跳过本次循环,继续执行下次循环
- break:结束整个循环
案例
案例一(回文数)
ini
/*
* 回文数
* 需求:给你一个整数X,如果X是回文数,返回true;否则,返回false。
*例如:121是回文数,而123不是。
*/
int x = 121;
int tmp = 121;
int num = 0;
while (x > 0) {
int ge = x % 10;
x = x / 10;
num = num * 10 + ge;
}
System.out.println(num == tmp);//true
案例二(求商和余数)
ini
/*
* 给定两个整数,被除数和除数(都是正数,且不超过int的范围)
* 将两个数相除,要求不能使用乘法,除法和 % 运算符
* 得到商和余数
*/
int dividend = 121;
int divisor = 10;
int count = 0;
while (dividend >= divisor) {
dividend = dividend - divisor;
count++;
}
System.out.println("商:" + count);
System.out.println("余数:" + dividend);
数组
介绍
- 数组指的是一种容器,可以用来存储同种数据类型的多个值
- 数组容器在存储数据的时候,需要结合隐式转换考虑
- 建议:容器的类型,和存储的数据类型保持一致
定义以及初始化
定义
- 格式一:数据类型[] 数组名
- 格式二:数据类型 数组名[]
初始化
初始化:就是在内存中,为数组容器开辟空间,并将数据存入容器中的过程 完整格式:数据类型[] 数组名=new 数据类型[]{元素1,元素2,元素3...}; 范例:int[] array=new int[]{11,22,33};
数组的地址值
c
//[I@5594a1b5 数组的地址值表示数组在内存中的位置
//[表示数组
//I表示int类型
//@表示一个间隔符号(固定格式)
//5594a1b5才是真正的地址值
int[] array = {11, 22, 33, 44, 55, 66, 77, 88, 99, 100};
System.out.println(array);//[I@5594a1b5
索引
- 索引:也叫下标,从0开始,逐个+1增长,连续不间断
- 数组元素访问:
- 利用索引对数组中的元素进行访问
- 格式:数组名[索引]
- 数据存储到数组
- 数组名[索引]=具体数据/变量
- 一旦覆盖之后,原来的数据就不存在了
数组遍历
概念
将数组中的所有的内容取出来
代码示例
ini
int[] array = {11, 22, 33, 44, 55, 66, 77, 88, 99, 100};
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
数组动态初始化
- 初始化时只指定数组长度,由系统为数组分配初始值
- 格式:数组类型[] 数组名=new 数组类型[长度];
在创建的时候,由我们自己指定数组的长度,由虚拟机给出默认的初始化值
数据类型 | 默认初始化值 |
---|---|
整数类型 | 0 |
小数类型 | 0.0 |
字符类型 | '/u0000' 空格 |
布尔类型 | false |
引用数据类型 | null |
数组动态初始化和静态初始化的区别
- 动态初始化:手动指定数组长度,由系统给出默认的初始化值
- 静态初始化:手动指定数组元素,系统会根据元素个数,计算出数组长度
数组常见问题
当访问了数组中不存在的索引,就会引发索引越界异常
数组常见操作
ini
// 声明和初始化数组
int[] arr1 = new int[5]; // 长度为5的int数组
String[] arr2 = {"a", "b", "c"}; // 初始化并赋值
// 访问和修改元素
arr1[0] = 10; // 赋值
int x = arr1[0]; // 取值
int length = arr1.length; // 获取数组长度(不是方法,是属性)
int[] numbers = {5, 3, 9, 1};
// 升序排序:[1, 3, 5, 9]
Arrays.sort(numbers);
// 部分排序,对索引1到3(不包括3)的元素排序
Arrays.sort(numbers, 1, 3);
// 返回元素索引,数组必须已排序才能正确使用
int index = Arrays.binarySearch(numbers, 5);
// 比较数组
int[] arrA = {1, 2, 3};
int[] arrB = {1, 2, 3};
boolean equal = Arrays.equals(arrA, arrB); // true
//填充数组
Arrays.fill(numbers, 0); // 将所有元素填充为0
Arrays.fill(numbers, 1, 3, 5); // 将索引1到3(不包括3)填充为5
//复制数组
int[] copy = Arrays.copyOf(numbers, numbers.length); // 复制整个数组
int[] partCopy = Arrays.copyOfRange(numbers, 1, 3); // 复制部分数组
//转化为字符串
String str = Arrays.toString(numbers); // 输出类似"[1, 2, 3]"
//转为列表
List<String> list = Arrays.asList("a", "b", "c");// 注意:返回的列表是固定大小的,不能添加/删除元素
//并行排序
Arrays.parallelSort(numbers); // 对大型数组并行排序
//流操作
Arrays.stream(numbers).filter(n -> n > 2).count();
//System.arraycopy方法
int[] src = {1, 2, 3, 4, 5};
int[] dest = new int[5];
System.arraycopy(src, 0, dest, 0, src.length); // 复制整个数组
// 参数:源数组, 源起始位置, 目标数组, 目标起始位置, 复制长度
//多维数组操作
int[][] matrix = {{1, 2}, {3, 4}};
int[][] matrix1 = {{1, 2}, {3, 4}};
int[][] matrix2 = {{5, 6}, {7, 8}};
String deepStr = Arrays.deepToString(matrix); // 深度转换为字符串
boolean deepEqual = Arrays.deepEquals(matrix1, matrix2); // 深度比较
//Java 8+ Stream API操作数组
int[] nums = {1, 2, 3, 4, 5};
// 转换为流并操作
int sum = Arrays.stream(nums).sum();
double avg = Arrays.stream(nums).average().orElse(0);
int max = Arrays.stream(nums).max().getAsInt();
// 过滤和映射
int[] evens = Arrays.stream(nums).filter(n -> n % 2 == 0).toArray();
方法
什么是方法
- 方法(method)是程序中最小的执行单元
- 重复的代码,具有独立功能的代码可以抽取到方法中
- 可以提高代码的复用性
- 可以代码的可维护性
方法的格式
最简单的方法:
arduino
public static void 方法名() {
方法体;
}
带参数的方法:
arduino
public static void 方法名(参数) {
方法体;
}
public static void 方法名(参数1 参数2...) {
方法体;
}
带返回值的方法:
arduino
public static 返回值类型 方法名(参数1 参数2...) {
方法体;
return 返回值;
}
小结:
- 方法不调用就不执行
- 方法与方法之间是平级关系,不能互相嵌套定义
- 方法的编写顺序与执行顺序无关
- 方法的返回值类型为void,表示方法没有返回值,没有返回值的方法可以省略return语句不写.如果要编写return,后面不能跟具体的数据
- return语句的下面,是不能编写代码,因为永远执行不到,属于无效的代码
return关键字:
- 方法没有返回值:可以省略不写.如果书写,表示结束方法
- 方法有返回值:必须要写.表示结束方法和返回结果
方法的重载
- 同一个类中,方法名相同,参数不同的方法.与返回值无关
- 参数不同:个数不同,类型不同,顺序不同
- 顺序不同可以构成重载,但是不建议
基本数据类型与引用数据类型
- 基本数据类型:数据值存储在自己的空间中.赋值给其他变量,也是赋的真实的值
- 引用数据类型:数据值存储在其他空间中,自己空间中存储的地址值.赋值给其他变量,赋的是地址值
方法的值传递
- 传递基本数据类型时,传递的是真实的数据,形参的改变,不影响实际参数的值
- 传递引用数据类型时,传递的是地址值,形参的改变,影响实际参数的值