基础知识与语法
Java分类
JavaSE 标准版,用于桌面程序、控制台开发
JavaME 嵌入式开发,手机、小家电,使用的人少。
JavaEE 企业级开发,web端、服务器开发,最广泛
JVM Java虚拟机,用于跨平台的实现
Javac将.java文件编译成.class文件,再通过Java运行
注释
单行注释 // 多行注释 /* */ 文档注释 /** * * */
Java程序的基本组成
//java的基本组成是类,定义一个类 public class 类名{ //main方法是程序的入口 public static void main(String[] args){ //输出语句 System.out.println() } }
标识符
程序中出现的类名、变量名、方法名、关键字等都是标识符
标识符以字母、数字、下划线、$组成,数字不能开头
驼峰命名法
小驼峰命名 :name firstName 针对方法、变量
大驼峰命名 :Name FirstName 针对 类
数据类型
Java作为强数据类型语言,变量必须先定义再使用。
int i = 0; 变量的初始化需要赋初值
基本类型 (数值类型)
字节 | 取值范围 | |
---|---|---|
byte | 1 | -128~127 |
short | 2 | -32768~32767 |
int | 4 | -2的31次方~2的31次方-1 |
long | 8 | -2的63次方~2的63次方-1 |
float | 4 | ~ |
double | 8 | ~ |
char | 2 | 0~65535 |
Boolean型 占一个字节 true 或 false
数据类型转换
自动数据转换 数据范围小到数据范围大 double i = 10; 10是int型,用double直接自动转换得到10.0
强制类型转换 范围大到小 int j = (int) 10.0 ; 得到10
long l = 100000000; 出错 默认是int类型 溢出 long l = 1000000L 正确
float d = 13.14; 错误 默认double类型 同理 float d = 13.14F正确
数据提升等级顺序
byte、short、char -> int -> long -> float -> double
表达式含多种数据类型,自动提升到最高等级的类型
扩展
二进制 0b开头 八进制0开头 十六进制0x开头
float有误差,不同浮点数可能相等,不用float比较数字大小
所有的字符本质是数字
‘A‘=65 ’a‘=97 ’0‘=48
运算符
算术运算符
操作符 | 描述 | 例子 |
---|---|---|
+ | 加法 - 相加运算符两侧的值 | A + B 等于 30 |
- | 减法 - 左操作数减去右操作数 | A – B 等于 -10 |
* | 乘法 - 相乘操作符两侧的值 | A * B等于200 |
/ | 除法 - 左操作数除以右操作数 | B / A等于2 |
% | 取余 - 左操作数除以右操作数的余数 | B%A等于0 |
++ | 自增: 操作数的值增加1 | B++ 或 ++B 等于 21(区别详见下文) |
-- | 自减: 操作数的值减少1 | B-- 或 --B 等于 19(区别详见下文) |
关系运算符
运算符 | 描述 | 例子 |
---|---|---|
== | 检查如果两个操作数的值是否相等,如果相等则条件为真。 | (A == B)为假。 |
!= | 检查如果两个操作数的值是否相等,如果值不相等则条件为真。 | (A != B) 为真。 |
> | 检查左操作数的值是否大于右操作数的值,如果是那么条件为真。 | (A> B)为假。 |
< | 检查左操作数的值是否小于右操作数的值,如果是那么条件为真。 | (A <B)为真。 |
>= | 检查左操作数的值是否大于或等于右操作数的值,如果是那么条件为真。 | (A> = B)为假。 |
<= | 检查左操作数的值是否小于或等于右操作数的值,如果是那么条件为真。 | (A <= B)为真。 |
位运算符
A=60 B=13
A = 0011 1100 B = 0000 1101 ----------------- A&B = 0000 1100 A | B = 0011 1101 A ^ B = 0011 0001 ~A= 1100 0011
操作符 | 描述 | 例子 |
---|---|---|
& | 如果相对应位都是1,则结果为1,否则为0 | (A&B),得到12,即0000 1100 |
| | 如果相对应位都是 0,则结果为 0,否则为 1 | (A | B)得到61,即 0011 1101 |
^ | 如果相对应位值相同,则结果为0,否则为1 | (A ^ B)得到49,即 0011 0001 |
〜 | 按位取反运算符翻转操作数的每一位,即0变成1,1变成0。 | (〜A)得到-61,即1100 0011 |
<< | 按位左移运算符。左操作数按位左移右操作数指定的位数。 | A << 2得到240,即 1111 0000 |
>> | 按位右移运算符。左操作数按位右移右操作数指定的位数。 | A >> 2得到15即 1111 |
>>> | 按位右移补零操作符。左操作数的值按右操作数指定的位数右移,移动得到的空位以零填充。 | A>>>2得到15即0000 1111 |
逻辑运算符
操作符 | 描述 | 例子 |
---|---|---|
&& | 称为逻辑与运算符。当且仅当两个操作数都为真,条件才为真。 | (A && B)为假。 |
| | | 称为逻辑或操作符。如果任何两个操作数任何一个为真,条件为真。 | (A | | B)为真。 |
! | 称为逻辑非运算符。用来反转操作数的逻辑状态。如果条件为true,则逻辑非运算符将得到false。 | !(A && B)为真。 |
短路原则
&& 两边为true 才为真,第一个假,后面不再执行
| | 一边为true 就为真,第一个真,后面不再执行
三元运算符
?:
b = (a == 1) ? 20 : 30; //a==1为true 则b=20 为false 则b=30
赋值运算符
操作符 | 描述 | 例子 |
---|---|---|
= | 简单的赋值运算符,将右操作数的值赋给左侧操作数 | C = A + B将把A + B得到的值赋给C |
+ = | 加和赋值操作符,它把左操作数和右操作数相加赋值给左操作数 | C + = A等价于C = C + A |
- = | 减和赋值操作符,它把左操作数和右操作数相减赋值给左操作数 | C - = A等价于C = C - A |
* = | 乘和赋值操作符,它把左操作数和右操作数相乘赋值给左操作数 | C * = A等价于C = C * A |
/ = | 除和赋值操作符,它把左操作数和右操作数相除赋值给左操作数 | C / = A,C 与 A 同类型时等价于 C = C / A |
(%)= | 取模和赋值操作符,它把左操作数和右操作数取模后赋值给左操作数 | C%= A等价于C = C%A |
<< = | 左移位赋值运算符 | C << = 2等价于C = C << 2 |
>> = | 右移位赋值运算符 | C >> = 2等价于C = C >> 2 |
&= | 按位与赋值运算符 | C&= 2等价于C = C&2 |
^ = | 按位异或赋值操作符 | C ^ = 2等价于C = C ^ 2 |
| = | 按位或赋值操作符 | C | = 2等价于C = C | 2 |
instanceof运算符
检查是否是特定类型(类类型或接口类型)
String name = "James"; boolean result = name instanceof String; // 由于 name 是 String 类型,所以返回真
Scanner数据输入
使用步骤
import java.util.Scanner //导包 必须在类定义上面 Scanner sc = new Scanner(System.in); //sc是变量名,可变,其他都不能变 int i = sc.intNext(); //接收数据 i是变量名可变,其他是固定格式 Scanner.close(); //用完关闭,节省资源占用,IO流都有占用资源的性质,及时关闭
判断是否有数据输入
if (Scanner.hasNext()){ //next方法接收 //输入 hello world //next接收 hello //nextline hello world //nextline接收数据更完整 }
结构语句
顺序结构
一条条语句顺着下来
选择语句(if、switch)
if语句
注意
-
if 语句至多有 1 个 else 语句,else 语句在所有的 else if 语句之后。
-
if 语句可以有若干个 else if 语句,它们必须在 else 语句之前。
-
一旦其中一个 else if 语句检测为 true,其他的 else if 以及 else 语句都将跳过执行。
-
一个if语句中可以嵌套另一个if语句
//格式1 if(布尔表达式) { //如果布尔表达式为true将执行的语句 } //格式2 if(布尔表达式){ //如果布尔表达式的值为true }else{ //如果布尔表达式的值为false } //格式3 if(布尔表达式 1){ //如果布尔表达式 1的值为true执行代码 }else if(布尔表达式 2){ //如果布尔表达式 2的值为true执行代码 }else if(布尔表达式 3){ //如果布尔表达式 3的值为true执行代码 }else { //如果以上布尔表达式都不为true执行代码 }
switch语句
//格式 根据表达式的值与相应case区域对应 //case都无法对应 运行default语句 switch(表达式){ case 值1: 语句体1; break; //可选,如果匹配成功,语句体1运行,有break,跳出switch语句,否则下面的case依次执行 case 值2: 语句体2; break; ... ... default: 语句体 }
switch case 语句有如下规则:
-
switch 语句中的变量类型可以是: byte、short、int 或者 char。从 Java SE 7 开始,switch 支持字符串 String 类型了,同时 case 标签必须为字符串常量或字面量。
-
switch 语句可以拥有多个 case 语句。每个 case 后面跟一个要比较的值和冒号。
-
case 语句中的值的数据类型必须与变量的数据类型相同,而且只能是常量或者字面常量。
-
当变量的值与 case 语句的值相等时,那么 case 语句之后的语句开始执行,直到 break 语句出现才会跳出 switch 语句。
-
当遇到 break 语句时,switch 语句终止。程序跳转到 switch 语句后面的语句执行。case 语句不必须要包含 break 语句。如果没有 break 语句出现,程序会继续执行下一条 case 语句,直到出现 break 语句。
-
switch 语句可以包含一个 default 分支,该分支一般是 switch 语句的最后一个分支(可以在任何位置,但建议在最后一个)。default 在没有 case 语句的值和变量值相等的时候执行。default 分支不需要 break 语句。
循环语句(for、while、do...while)
for循环
for(初始化; 布尔表达式; 更新) { //代码语句 }
关于 for 循环有以下几点说明:
-
最先执行初始化步骤。可以声明一种类型,但可初始化一个或多个循环控制变量,也可以是空语句。
-
然后,检测布尔表达式的值。如果为 true,循环体被执行。如果为false,循环终止,开始执行循环体后面的语句。
-
执行一次循环后,更新循环控制变量。
-
再次检测布尔表达式。循环执行上面的过程。
Java增强for循环 用于数组
声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循环语句块,其值与此时数组元素的值相等。
表达式:表达式是要访问的数组名,或者是返回值为数组的方法。
for(声明语句 : 表达式) { //代码句子 }
while循环
初始化语句 //只要布尔表达式为 true,循环就会一直执行下去。 while( 布尔表达式 ) { //循环内容 //continue 跳过本次循环 执行下一次 //break 结束while循环 }
do ...while循环
初始化语句 do { //代码语句 }while(布尔表达式);
方法
-
修饰符:修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。
-
返回值类型 :方法可能会返回值。returnValueType 是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType 是关键字void。
-
方法名:是方法的实际名称。方法名和参数表共同构成方法签名。
-
参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
-
方法体:方法体包含具体的语句,定义该方法的功能。
格式
修饰符 返回值类型 方法名(参数类型 参数名){ ... 方法体 ... return 返回值; } public static void main(int i) // 修饰符 返回值类型 方法名 println() 是一个方法。 System 是系统类。 out 是标准输出对象。
方法调用
public static void main(String[] args) { int i = 5; int j = 2; int k = max(i, j); public static int max(int number1 , int number2)
方法重载
扩展方法的适用范围
声明两个同名的方法,使用范围不同,一个适用于int 一个适用double
则这个方法重载适用于int double
可变参数
//格式 typeName... parameterName //使用 建立一个方法 求最大值 public static void printMax( double... numbers) { //调用 printMax(34, 3, 3, 2, 56.5); //把输入的参数改变了,只保留了索引为1、2、3的值,并在这三个数字中找最大值 //参数的改变包括增加,相当于一个可加长的数组 printMax(new double[]{1, 2, 3}); //输出 The max value is 56.5 The max value is 3.0
在方法声明中,在指定参数类型后加一个省略号(...) 。
一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它之前声明。
递归
A方法调用A方法 能不用递归就不用,太耗资源
//求阶乘 public class gs { public static void main(String[] args) { //求5的阶乘 System.out.println(f(5)); } public static int f(int n){ if(n==1){ return 1; }else{ return n * f( n-1); } } } //要在递归中能够终止程序,不能陷入死循环
数组
相同类型数据的有序集合
//声明数组变量格式 double[] myList; // 首选的方法 或 double myList[]; // 效果相同,但不是首选方法
创建数组
先创建数组,再初始化
nums = new int[10]; //数组变量的声明,和创建数组可以用一条语句完成,如下所示: int[] numbers = new int[10]; //也可以用 int [] array = {1.2.3.4};
数组的元素类型和数组的大小都是确定的,所以当处理数组元素时候,我们通常使用基本循环或者
For-Each 循环。
for(int element: array) { //打印所有数组元素 System.out.println(element); }
java.util.Arrays 类能方便地操作数组,它提供的所有方法都是静态的。
-
给数组赋值:通过 fill 方法。
-
对数组排序:通过 sort 方法,按升序。
-
比较数组:通过 equals 方法比较数组中元素值是否相等。
-
查找数组元素:通过 binarySearch 方法能对排序好的数组进行二分查找法操作。
序号 | 方法和说明 |
---|---|
1 | public static int binarySearch(Object[] a, Object key) 用二分查找算法在给定数组中搜索给定值的对象(Byte,Int,double等)。数组在调用前必须排序好的。如果查找值包含在数组中,则返回搜索键的索引;否则返回 (-(插入点) - 1)。 |
2 | public static boolean equals(long[] a, long[] a2) 如果两个指定的 long 型数组彼此相等,则返回 true。如果两个数组包含相同数量的元素,并且两个数组中的所有相应元素对都是相等的,则认为这两个数组是相等的。换句话说,如果两个数组以相同顺序包含相同的元素,则两个数组是相等的。同样的方法适用于所有的其他基本数据类型(Byte,short,Int等)。 |
3 | public static void fill(int[] a, int val) 将指定的 int 值分配给指定 int 型数组指定范围中的每个元素。同样的方法适用于所有的其他基本数据类型(Byte,short,Int等)。 |
4 | public static void sort(Object[] a) 对指定对象数组根据其元素的自然顺序进行升序排列。同样的方法适用于所有的其他基本数据类型(Byte,short,Int等)。 |
冒泡排序
比较数组两个相邻元素,比较大小,小的或者大的排前面,依次完成使数组从小到大或从大到小排列。
稀疏数组
数组大部分是零或同一值,用稀疏数组保存。
处理
把不同的值放一个小数组中保存,坐标形式
行 | 列 | 值 | |
---|---|---|---|
1 | 0行 | 2列 | 20 |
2 | |||
3 |
//创建二维数组,并赋两个值 int[][] arrays = new int[11][11]; arrays [1][2]= 1; arrays [2][3] = 2; System.out.println("输出原始数组:"); for (int[] ints: arrays){ //遍历二维数组 for..each方法 for(int anInt: ints){ //两个ints分别代表element和数组 System.out.print(anInt+"\t"); } System.out.println(); //for循环得出数组有效值的个数,稀疏数组有三列,行、列、值,通过上一个for循环可以得到(有效值sum)+1行 //稀疏数组 int[][] arrays2 = new int[有效值+1][3] arrays2[0][0] = 11; //存了多少行 arrays2[0][1] = 11; //存了多少列 arrays2[0][2] = sum; //存了多少个数 都是作为表头存储 如下,刚开始不知道多少行列,取最大的
行 | 列 | 值 | |
---|---|---|---|
1 | 0行 | 2列 | 20 |
//遍历二维数组,将非零值存到稀疏数组 //还原稀疏数组,稀疏数组第一行是行、列、有效值的信息 int[][] arrays3 = new int[arrays2[0][0]][arrays2[0][1]];//遍历,依次保存即可