1、标识符
由字母、下划线、美元符号或者数字组成。且必须以下划线、字母、美元符号开头
2、关键字
java中有48个常用关键字和2个保留字
48个关键字:
- abstract: 用于声明抽象类,以及抽象方法。
- boolean: 用于将变量声明为布尔值类型,只有 true 和 false 两个值。
- break: 用于中断循环或 switch 语句。
- byte: 用于声明一个可以容纳 8 个比特的变量。
- case: 用于在 switch 语句中标记条件的值。
- catch: 用于捕获 try 语句中的异常。
- char: 用于声明一个可以容纳无符号位比特的的变量。
- class: 用于声明一个类。
- continue: 用于继续下一个循环,可以在指定条件下跳过其余代码。
- default: 用于指定 switch 语句中除去 case 条件之外的默认代码块。
- do: 通常和 while 关键字配合使用,do 后紧跟循环体。
- double: 用于声明一个可以容纳 64 位浮点数的变量。
- else: 用于指示 if 语句中的备用分支。
- enum: 用于定义一组固定的常量(枚举)。
- extends: 用于指示一个类是从另一个类或接口继承的。
- final: 用于指示该变量是不可更改的。
- finally: 和
try-catch
配合使用,表示无论是否处理异常,总是执行 finally 块中的代码。 - float: 用于声明一个可以容纳 32 位浮点数的变量。
- for: 用于声明一个 for 循环,如果循环次数是固定的,建议使用 for 循环。
- if: 用于指定条件,如果条件为真,则执行对应代码。
- implements: 用于实现接口。
- import: 用于导入对应的类或者接口。
- instanceof: 用于判断对象是否属于某个类型(class)。
- int: 用于声明一个可以容纳 32 位带符号的整数变量。
- interface: 用于声明接口。
- long: 用于声明一个可以容纳 64 位整数的变量。
- native: 用于指定一个方法是通过调用本机接口(非 Java)实现的。
- new: 用于创建一个新的对象。
- null: 如果一个变量是空的(什么引用也没有指向),就可以将它赋值为 null,和空指针异常息息相关。
- package: 用于声明类所在的包。
- private: 一个访问权限修饰符,表示方法或变量只对当前类可见。
- protected: 一个访问权限修饰符,表示方法或变量对同一包内的类和所有子类可见。
- public: 一个访问权限修饰符,除了可以声明方法和变量(所有类可见),还可以声明类。
main()
方法必须声明为 public。 - return: 用于在代码执行完成后返回(一个值)。
- short: 用于声明一个可以容纳 - 位整数的变量。
- static: 表示该变量或方法是静态变量或静态方法。
- strictfp: 并不常见,通常用于修饰一个方法,确保方法体内的浮点数运算在每个平台上执行的结果相同。
- super: 可用于调用父类的方法或者字段。
- switch: 通常用于三个(以上)的条件判断。
- synchronized: 用于指定多线程代码中的同步方法、变量或者代码块。
- this: 可用于在方法或构造函数中引用当前对象。
- throw: 主动抛出异常。
- throws: 用于声明异常。
- transient: 修饰的字段不会被序列化。
- try: 于包裹要捕获异常的代码块。
- void: 用于指定方法没有返回值。
- volatile: 保证不同线程对它修饰的变量进行操作时的可见性,即一个线程修改了某个变量的值,新值对其他线程来说是立即可见的。
- while: 如果循环次数不固定,建议使用 while 循环。
2个保留字:
-
goto: 在 C语言中叫做‘无限跳转’语句,在 Java 中,不再使用 goto 语句,因为无限跳转会破坏程序结构。
-
const: 在 C语言中是声明常量的关键字,在 Java 中可以使用 public static final 三个关键字的组合来达到常量的效果。
3、修饰符
访问控制修饰符
Java中,可以使用访问控制符来保护对类、变量、方法和构造方法的访问。Java 支持 4 种不同的访问权限。
- default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
- private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
- public : 对所有类可见。使用对象:类、接口、变量、方法
- protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类) 。
我们可以通过以下表来说明访问权限:
访问控制和继承
- 父类中声明为 public 的方法在子类中也必须为 public。
- 父类中声明为 protected 的方法在子类中要么声明为 protected,要么声明为 public,不能声明为 private。
- 父类中声明为 private 的方法,不能够被继承。
非访问修饰符
static 修饰符,用来修饰类方法和类变量。
final 修饰符,用来修饰类、方法和变量,final 修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的。
abstract 修饰符,用来创建抽象类和抽象方法。
synchronized 和 volatile 修饰符,主要用于线程的编程。
static 修饰符
-
静态变量:
static 关键字用来声明独立于对象的静态变量,无论一个类实例化多少对象,它的静态变量只有一份拷贝。 静态变量也被称为类变量。局部变量不能被声明为 static 变量。
-
静态方法:
static 关键字用来声明独立于对象的静态方法。静态方法不能使用类的非静态变量。静态方法从参数列表得到数据,然后计算这些数据。
对类变量和方法的访问可以直接使用 classname.variablename 和 classname.methodname 的方式访问。
静态方法不能使用本类的非静态方法和变量,但是非静态方法可以使用静态方法、静态变量
final 修饰符
final 变量
final 表示"最后的、最终的"含义,变量一旦赋值后,不能被重新赋值。被 final 修饰的实例变量必须显式指定初始值。
final 修饰符通常和 static 修饰符一起使用来创建类常量。
final 方法
父类中的 final 方法可以被子类继承,但是不能被子类重写。
声明 final 方法的主要目的是防止该方法的内容被修改。
abstract 修饰符
抽象类:
抽象类不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类进行扩充。
一个类不能同时被 abstract 和 final 修饰。如果一个类包含抽象方法,那么该类一定要声明为抽象类,否则将出现编译错误。
抽象类可以包含抽象方法和非抽象方法。
抽象方法
抽象方法是一种没有任何实现的方法,该方法的的具体实现由子类提供。
抽象方法不能被声明成 final 和 static。
任何继承抽象类的子类必须实现父类的所有抽象方法,除非该子类也是抽象类。
如果一个类包含若干个抽象方法,那么该类必须声明为抽象类。抽象类可以不包含抽象方法。
synchronized 修饰符
synchronized 关键字声明的方法同一时间只能被一个线程访问。
transient 修饰符
序列化的对象包含被 transient 修饰的实例变量时,java 虚拟机(JVM)跳过该特定的变量。
该修饰符包含在定义变量的语句中,用来预处理类和变量的数据类型。
volatile 修饰符
volatile 修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值。而且,当成员变量发生变化时,会强制线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
一个 volatile 对象引用可能是 null。
4、变量
Java 局部变量
- 局部变量声明在方法、构造方法或者语句块中;
- 局部变量在方法、构造方法、或者语句块被执行的时候创建,当它们执行完成后,变量将会被销毁;
- 访问修饰符不能用于局部变量;
- 局部变量只在声明它的方法、构造方法或者语句块中可见;
- 局部变量是在栈上分配的。
- 局部变量没有默认值,所以局部变量被声明后,必须经过初始化,才可以使用。
实例变量
- 实例变量声明在一个类中,但在方法、构造方法和语句块之外;
- 当一个对象被实例化之后,每个实例变量的值就跟着确定;
- 实例变量在对象创建的时候创建,在对象被销毁的时候销毁;
- 实例变量的值应该至少被一个方法、构造方法或者语句块引用,使得外部能够通过这些方式获取实例变量信息;
- 实例变量可以声明在使用前或者使用后;
- 访问修饰符可以修饰实例变量;
- 实例变量对于类中的方法、构造方法或者语句块是可见的。一般情况下应该把实例变量设为私有。通过使用访问修饰符可以使实例变量对子类可见;
- 实例变量具有默认值。数值型变量的默认值是0,布尔型变量的默认值是false,引用类型变量的默认值是null。变量的值可以在声明时指定,也可以在构造方法中指定;
- 实例变量可以直接通过变量名访问。但在静态方法以及其他类中,就应该使用完全限定名:ObejectReference.VariableName。
类变量(静态变量)
- 类变量也称为静态变量,在类中以 static 关键字声明,但必须在方法之外。
- 无论一个类创建了多少个对象,类只拥有类变量的一份拷贝。
- 静态变量除了被声明为常量外很少使用,静态变量是指声明为 public/private,final 和 static 类型的变量。静态变量初始化后不可改变。
- 静态变量储存在静态存储区。经常被声明为常量,很少单独使用 static 声明变量。
- 静态变量在第一次被访问时创建,在程序结束时销毁。
- 与实例变量具有相似的可见性。但为了对类的使用者可见,大多数静态变量声明为 public 类型。
- 默认值和实例变量相似。数值型变量默认值是 0,布尔型默认值是 false,引用类型默认值是 null。变量的值可以在声明的时候指定,也可以在构造方法中指定。此外,静态变量还可以在静态语句块中初始化。
- 静态变量可以通过:ClassName.VariableName的方式访问。
- 类变量被声明为 public static final 类型时,类变量名称一般建议使用大写字母。如果静态变量不是 public 和 final 类型,其命名方式与实例变量以及局部变量的命名方式一致。
5、java注释
java注释主要有单行注释、多行注释、文档注释
单行注释
单行注释用来解释方法内某行代码的作用。阿里巴巴开发规约不建议写在行尾,应该在被注释语句上方另起一行,使用 //
注释。
public void method() {
// name 用于表示姓名
String name = "ikun";
}
多行注释
通常用于解释一段代码的作用。以 /*
开始,以 */
结束。
public void method() {
/*
* name 用于表示姓名
* practiceTime表示练习时长
*/
String name = "ikun";
String practiceTime= "两年半";
}
文档注释
文档注释可用在三个地方,类、字段和方法,用来解释作用
/**
* demo测试
*/
public class Demo {
/**
* 年龄
*/
private int age;
/**
* main 方法作为程序的入口
*
* @param args 参数
*/
public static void main(String[] args) {
}
}
javadoc命令
-
利用代码点击右键open in Terminal
-
输入命令:javadoc .\HelloController.java -encoding utf-8
-
输入命令ls,查看生成的文件列表:
-
在浏览器打开index.html即可查看该类注释文档
注意事项:
1)javadoc
命令只能为 public 和 protected 修饰的字段、方法和类生成文档。
default 和 private 修饰的字段和方法的注释将会被忽略掉。因为我们本来就不希望这些字段和方法暴露给调用者。
2)文档注释中可以嵌入一些 HTML 标记,比如说段落标记 <p>
,超链接标记 <a></a>
等等,但不要使用标题标记,比如说 <h1>
,因为 javadoc 会插入自己的标题,容易发生冲突。
3)文档注释中可以插入一些 @
注解,比如说 @see
引用其他类,@version
版本号,@param
参数标识符,@author
作者标识符,@deprecated
已废弃标识符,等等
注释规约
1) 注释必须能够描述业务含义,能够让其他程序员能够了解代码含义
2) 注释要能够清晰的反映设计思想和代码逻辑
3) 一般在类头添加创建者和创建时间,可通过idea设置中的File and Code Templates配置
4) 在类、字段、方法尽量使用文档注释;枚举字段类型加注释;代码修改之后注释要记得更新修改
6、数据类型
数据类型分为基本数据类型和引用数据类型
基本数据类型
类型 | 名称 | 大小 | 默认值 | 包装类 | 取值范围 |
---|---|---|---|---|---|
字节型 | byte | 1字节 | 0 | Byte | -2^7~2^7-1 |
整型 | short | 2字节 | 0 | Short | -2^15~2^15-1 |
整型 | int | 4字节 | 0 | Integer | -2^31~2^31 |
整型 | long | 8字节 | 0L | Long | -2^63~2^63-1 |
浮点型 | float | 4字节 | 0.0f | Float | 见IEE754标准 |
浮点型 | double | 8字节 | 0.0 | Double | 见IEE754标准 |
字符型 | char | 2字节 | '\u0000'(空格) | Character | '\u0000'(0)到 '\uffff'(65,535) |
布尔型 | boolean | 1比特 | false | Boolean | true和false |
补充:
1)浮点数double和float不太适合精度数值,精确的数值可使用BigDecimal表示
2)char占用两个字节是因为采用的Unicode字符集而不是ASCII 字符集。Unicode字符集编码占用两个字节
引用数据类型
除了基本数据类型以外都是引用数据类型,常见的有数组、类等。引用数据类型的默认值为null。
7、数据类型转换
自动类型转换
必须满足转换前的数据类型的位数要低于转换后的数据类型,并且两者数据类型相互兼容。例如: short数据类型的位数为16位,就可以自动转换位数为32的int类型,同样float数据类型的位数为32,可以自动转换为64位的double类型。
- 数值型数据的转换:byte→short→int→long→float→double。
- 字符型转换为整型:char→int。
以上数据类型的转换遵循从左到右的转换顺序,最终转换成表达式中表示范围最大的变量的数据类型。
强制数据类型转换
当两种数据类型不兼容,或目标类型的取值范围小于源类型时,自动转换将无法进行,这时就需要进行强制类型转换。其语法格式如下:
(type)variableName
//示例
int a = 6;
double b = 8.0;
a = (int)b;
总结
boolean类型不能转换为其他类型,其他类型也不可以转换为boolean
整型、字符型、浮点型的数据在混合运算中相互转换,原则:
1、容量小的类型自动转换为容量大的数据类型:byte,short,char-int-long-float-double
2、byte\short\char之间不会相互转换,他们三者在计算时会自动转换为int
3、容量大的数据类型转换为容量小的数据类型时,强制转换会造成精度降低或溢出
4、多种类型的数据混合运算时,系统首先会自动将所有数据转换为容量最大的哪一种数据类型,然后再计算
5、实数常量 1.2 默认为double ; 整数常量 123 默认为Int
6、浮点数到整数的转换是通过舍弃小数得到,而不是四舍五入
8、命名规范
包(package)
包的命名应该遵守以下规则:
- 应该全部是小写字母
- 点分隔符之间有且仅有一个自然语义的英语单词
- 包名统一使用单数形式,比如说
com.study.util
不能是com.study.utils
- 在最新的 Java 编程规范中,要求开发人员在自己定义的包名前加上唯一的前缀。由于互联网上的域名是不会重复的,所以多数开发人员采用自己公司(或者个人博客)在互联网上的域名称作为包的唯一前缀。
类(class)
类的命名应该遵守以下规则:
- 必须以大写字母开头
- 最好是一个名词,比如说 System
- 类名使用 UpperCamelCase(驼峰式命名)风格
- 尽量不要省略成单词的首字母,但以下情形例外:DO/BO/DTO/VO/AO/PO/UID 等
另外,如果是抽象类的话,使用 Abstract 或 Base 开头;如果是异常类的话,使用 Exception 结尾;如果是测试类的话,使用 Test 结尾。
接口(interface)
接口的命名应该遵守以下规则:
- 必须以大写字母开头
- 最好是一个形容词,比如说 Runnable
- 尽量不要省略成单词的首字母
来看个例子:
interface Printable {}
接口和实现类之间也有一些规则:
- 实现类用 Impl 的后缀与接口区别,比如说 CacheServiceImpl 实现 CacheService 接口
- 或者,AbstractTranslator 实现 Translatable 接口
字段(field)和变量(variable)
字段和变量的命名应该遵守以下规则:
- 必须以小写字母开头
- 可以包含多个单词,第一个单词的首字母小写,其他的单词首字母大写,比如说
firstName
- 最好不要使用单个字符,比如说
int a
,除非是局部变量 - 类型与中括号紧挨相连来表示数组,比如说
int[] arrayDemo
,main 方法中字符串数组参数不应该写成String args[]
- POJO 类中的任何布尔类型的变量,都不要加 is 前缀,否则部分框架解析会引起序列化错误,例如fastjson
- 避免在子类和父类的成员变量之间、或者不同代码块的局部变量之间采用完全相同的命名,使可理解性降低。子类、父类成员变量名相同,即使是 public 类型的变量也能够通过编译,另外,局部变量在同一方法内的不同代码块中同名也是合法的,这些情况都要避免。
常量(constant)
常量的命名应该遵守以下规则:
- 应该全部是大写字母
- 可以包含多个单词,单词之间使用“_”连接,比如说
MAX_PRIORITY
,力求语义表达完整清楚,不要嫌名字长 - 可以包含数字,但不能以数字开头
来看个例子:
static final int MIN_AGE = 18;
方法(method)
方法的命名应该遵守以下规则:
- 必须以小写字母开头
- 最好是一个动词,比如说
print()
- 可以包含多个单词,第一个单词的首字母小写,其他的单词首字母大写,比如说
actionPerformed()
来看个例子:
void writeBook(){}
Service/DAO 层的方法命名规约:
- 获取单个对象的方法用 get 做前缀
- 获取多个对象的方法用 list 做前缀,复数结尾,如:listObjects
- 获取统计值的方法用 count 做前缀
- 插入的方法用 save/insert 做前缀
- 删除的方法用 remove/delete 做前缀
- 修改的方法用 update 做前缀
总结
除了以上这些规则以外,还有一些共同的规则需要遵守,比如说:
- 代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束。反例:
_name / __name / $name / name_ / name$ / name__
- 所有编程相关的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式。反例:
DaZhePromotion [打折] / getPingfenByName() [评分] / String fw[福娃] / int 某变量 = 3
- 代码和注释中都要避免使用任何语言的种族歧视性词语。反例:
RIBENGUIZI / Asan / blackList / whiteList / slave
- 方法名、参数名、成员变量、局部变量都统一使用 lowerCamelCase 风格。
- 杜绝完全不规范的缩写,避免望文不知义。反例:AbstractClass “缩写”成 AbsClass;condition “缩写”成 condi;Function 缩写”成 Fu,此类随意缩写严重降低了代码的可阅读性。
- 为了达到代码自解释的目标,任何自定义编程元素在命名时,使用尽量完整的单词组合来表达。
- 在常量与变量的命名时,表示类型的名词放在词尾,以提升辨识度。正例:
startTime / workQueue / nameList / TERMINATED_THREAD_COUNT
- 如果模块、接口、类、方法使用了设计模式,在命名时需体现出具体模式。 将设计模式体现在名字中,有利于阅读者快速理解架构设计理念。比如说:
public class OrderFactory;public class LoginProxy;public class ResourceObserver;
- 枚举类名带上 Enum 后缀,枚举成员名称需要全大写,单词间用下划线隔开。枚举其实就是特殊的常量类,且构造方法被默认强制是私有。比如说:
枚举名字为 ProcessStatusEnum 的成员名称:SUCCESS / UNKNOWN_REASON
。
9、运算符
java运算符包含算术运算符、逻辑运算符、关系运算符、位运算符、赋值运算符、其他运算符
算术运算符
常见的加减乘除等
逻辑运算符
-
逻辑与运算符(&&):多个条件中只要有一个为 false 结果就为 false。
-
逻辑或运算符(||):多个条件只要有一个为 true 结果就为 true。
-
逻辑非运算符(!):用来反转条件的结果,如果条件为 true,则逻辑非运算符将得到 false。
-
单逻辑与运算符(&):很少用,因为不管第一个条件为 true 还是 false,依然会检查第二个。
-
单逻辑或运算符(|):也会检查第二个条件。
关系运算符
关系运算符(> >= < <=)用来比较两个操作数,返回结果为 true 或者 false。
位运算符
操作符 | 描述 | 例子 |
---|---|---|
& | 如果相对应位都是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 |
因为计算机是采用二进制进行存储,所以一般使用位运算可以提高运行效率
例如: HashMap 在计算哈希值的时候:
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
赋值运算符
= + = - = * = / =%= >> = << =&= ^ = | =
运算符优先级
类别 | 操作符 | 关联性 |
---|---|---|
后缀 | () [] . (点操作符) | 左到右 |
一元 | expr++ expr-- | 从左到右 |
一元 | ++expr --expr + - ~ ! | 从右到左 |
乘性 | * /% | 左到右 |
加性 | + - | 左到右 |
移位 | >> >>> << | 左到右 |
关系 | > >= < <= | 左到右 |
相等 | == != | 左到右 |
按位与 | & | 左到右 |
按位异或 | ^ | 左到右 |
按位或 | | | 左到右 |
逻辑与 | && | 左到右 |
逻辑或 | | | | 左到右 |
条件 | ?: | 从右到左 |
赋值 | = + = - = * = / =%= >> = << =&= ^ = | = | 从右到左 |
逗号 | , | 左到右 |
注意事项
- 当浮点数除以 0 的时候,结果为 Infinity 或者 NaN。
System.out.println(10.0 / 0.0); // Infinity
System.out.println(0.0 / 0.0); // NaN
//Infinity 的中文意思是无穷大
//NaN 的中文意思是这不是一个数字(Not a Number)。
- 当整数除以 0 的时候(
10 / 0
),会抛出异常,所以整数在进行除法运算时,需要先判断除数是否为 0,以免程序抛出异常。
Exception in thread "main" java.lang.ArithmeticException: / by zero
at com.itwanger.eleven.ArithmeticOperator.main(ArithmeticOperator.java:32)
- 一元运算符可以放在数字的前面或者后面,放在前面叫前自增(前自减),放在后面叫后自增(后自减)。前自增和后自增是有区别的,拿
int y = ++x
这个表达式来说(x = 10),它可以拆分为x = x+1 = 11; y = x = 11
,所以表达式的结果为x = 11, y = 11
。拿int y = x++
这个表达式来说(x = 10),它可以拆分为y = x = 10; x = x+1 = 11
,所以表达式的结果为x = 11, y = 10
。另外在前在后运算优先级也是不同的。
int x = 10;
int y = ++x;
System.out.println(y + " " + x);// 11 11
x = 10;
y = x++;
System.out.println(y + " " + x);// 10 11
10、流程控制
if语句
if 语句的格式如下:
if(布尔表达式){
// 如果条件为 true,则执行这块代码
}
if-else语句
if-else 语句的格式如下:
if(布尔表达式){
// 条件为 true 时执行的代码块
}else{
// 条件为 false 时执行的代码块
}
如果执行语句比较简单的话,可以使用三元运算符来代替 if-else 语句,如果条件为 true,返回 ? 后面 : 前面的值;如果条件为 false,返回 : 后面的值。
if-else-if语句
if-else-if 语句的格式如下:
if(条件1){
// 条件1 为 true 时执行的代码
}else if(条件2){
// 条件2 为 true 时执行的代码
}
else if(条件3){
// 条件3 为 true 时执行的代码
}
...
else{
// 以上条件均为 false 时执行的代码
}
if嵌套语句
if 嵌套语句的格式如下:
if(外侧条件){
// 外侧条件为 true 时执行的代码
if(内侧条件){
// 内侧条件为 true 时执行的代码
}
}
switch
switch(expression){
case value :
//语句
break; //可选
case value :
//语句
break; //可选
//你可以有任意数量的case语句
default : //可选
//语句
}
switch 语句中的变量类型可以是: byte、short、int 或者 char。从 Java SE 7 开始,switch 支持字符串 String 类型了,同时 case 标签必须为字符串常量或字面量。
switch 语句可以包含一个 default 分支,该分支一般是 switch 语句的最后一个分支(可以在任何位置,但建议在最后一个)。default在没有 case 语句的值和变量值相等的时候执行。default 分支不需要 break 语句。
for 循环
1)普通 for 循环
普通的 for 循环可以分为 4 个部分:
1)初始变量:循环开始执行时的初始条件。
2)条件:循环每次执行时要判断的条件,如果为 true,就执行循环体;如果为 false,就跳出循环。当然了,条件是可选的,如果没有条件,则会一直循环。
3)循环体:循环每次要执行的代码块,直到条件变为 false。
4)自增/自减:初始变量变化的方式。
来看一下普通 for 循环的格式:
for(初始变量;条件;自增/自减){
// 循环体
}
2)for-each
for-each 循环通常用于遍历数组和集合,它的使用规则比普通的 for 循环还要简单,不需要初始变量,不需要条件,不需要下标来自增或者自减。来看一下语法:
for(元素类型 元素 : 数组或集合){
// 要执行的代码
}
while 循环
来看一下 while 循环的格式:
while(条件){
//循环体
}
把 while 的条件设置为 true,并且循环体中没有 break 关键字的话,程序一旦运行起来,就根本停不下来了,除非强制停止。
do-while 循环
来看一下 do-while 循环的格式:
do{
// 循环体
}while(提交);
把 do-while 的条件设置为 true,并且循环体中没有 break 关键字的话,程序一旦运行起来,就根本停不下来了,除非强制停止。
11、数组
数组是一种线性数据结构,是一个使用连续的内存空间存放相同的数据类型的集合容器,与其他容器相比,数组的区别主要在于性能与保存基本类型的能力。
在Java中,数组是一种效率最高的存储和随机访问对象的方式,通过寻址公式,随机访问的时间复杂可以达到O(1),但是为了保持空间的连续性,在数组中插入、删除数据时,都需要移动后面数据,该操作的时间复杂度为O(n)。另外,由于空间上连续,所以数组对CPU缓存比较友好,借助CPU的缓存机制,预读数组中的数据,提高访问效率。但是,由于数组是定长的,一旦声明之后就不可以改变长度,所以如果长度声明过大或者过小都会造成问题。
一维数组
一维数组的逻辑结构是线性表,它是最简单的数组。数组定义必须要初始化长度。因为数据是不可变的所以初始化之后,需要分配的空间就固定下来了。
二维数组
二维数组可以看作是一张表,具有行和列。