一、Java 概述
1.1 Java 特性
Java是一门面向对象的编程语言,它吸收了 C++ 语言的各种优点,又摒弃了难以理解的多继承、指针等概念。Java 具有以下11个特性:
- 简单性:语法为 C++ 的纯净版,支持在小型机器进行开发;
- 面向对象:面向对象设计将重点放在数据(即对象)和对象的接口上,接口取代了 C++ 中的多重继承;
- 分布式:Java 有丰富的例程库用于处理 TCP/IP 协议,其应用程序能够通过 URL 打开和访问网络上的对象;
- 健壮性:早期的问题检测,即Java 编译器能够检测很多在其他语言中运行时才能检测的问题,后期的动态检测(运行时),Java 与 C/C++ 最大的不同在于 Java 采用的指针模型可以消除重写内存和损坏数据的可能性;
- 安全性:适用于网络/分布式环境,防范各种攻击包括:运行时的堆栈溢出即蠕虫和病毒常用的攻击手段、破坏自己的进程空间之外的内存、未经授权读写文件;
- 体系结构中立:Java 编译器通过生成一个体系结构中立的目标文件格式,即字节码文件件。精心设计的字节码文件不仅可以很容易在任何机器上解释运行,而且可以通过动态转换成本地机器代码,成为即时编译;
- 可移植性:Java 中数值类型有固定的字节数,字符串则采用标准的 Unicode 格式存储;
- 解释型:Java 解释器可以在任何移植了解释器的机器上直接运行 Java 字节码;
- 高性能:字节码可以在运行时动态地转换成对应运行这个应用的特定 CPU 的机器码;
- 多线程:多线程可以带来更快的交互相应和实时行为;
- 动态性:库中可以自由地添加新方法和新的实例变量,而对客户端没有影响;
Java常用术语如下:
术语名 | 缩写 | 解释 |
---|---|---|
JAVA Runtime Environment(Java运行环境) | JRE | 运行 Java 程序用户使用的软件 |
Java Development Kit(Java 开发工具) | JDK | 编写 Java 程序的程序员使用的软件 |
Server JRE(服务器JRE) | - | 在服务器上运行 Java 程序的软件 |
Standard Edition (标准版) | SE | Java 技术的核心和基础,用于桌面或简单服务器应用的平台 |
Enterprise Edition(企业版) | EE | 用于复杂服务器应用的 Java 平台 |
Micro Edition(微型版) | ME | 用于小型设备的 Java 平台 |
Java Virtual Machine | JVM | Java 虚拟机用于运行 Java 字节码文件的虚拟计算机 |
1.2 Java 运行机制
计算机的高级语言按照程序的执行方式可以分为编译型和解释型两种。
- 编译型语言是指使用专门的编译器,针对特定平台(操作系统)将某种高级语言源代码一次性“翻译”成可被该平台硬件执行的机器码,并包装成该平台所能识别的可执行程序的格式,这个转换过程称为编译。有些程序编译结束后还需要对目标代码进行链接,即组装两个以上的目标代码模块生成最终的可执行程序,实现低层次的代码复用。常见的C/C++、Objective-C、Pascal 等高级语言都属于编译型语言
- 解释型语言是指使用专门的解释器对源程序逐行解释成特定平台的机器码并立即执行的语言,解释型语言相当于把编译型语言中的编译和解释过程混合到一起同时完成。因为每次执行解释型语言的程序都需要进行一次编译,通常效率较低且不能脱离解释器独立运行。优势是跨平台移植容易,但这是牺牲程序执行效率为代价的。常见的 Ruby、Python 等语言都属于解释型语言。
Java是一种特殊的高级语言,需要经过先编译(javac HelloWorld.java
)生成与平台无关的字节码文件(*.class文件),字节码文件需要通过 Java 解释器(java HelloWorld
)来执行。Java语言中负责解释执行字节码文件的是 Java 虚拟机,不同的平台上的 JVM 是不同的,但它们都提供了相同的接口。
JVM的作用可以类比:有两只不同的笔和同一个笔帽,只有为这两支笔分别提供一个转换器。这个转换器向上的接口相同,用于适应同一个笔帽;向下的接口不同,用于适应两只不同的笔。可以理解两只不同的笔就是不同的操作系统,而同一个笔帽就是 Java 字节码文件,转换器则对应JVM。
JDK 包含Java 编译器、Java运行环境(JRE)以及常用的 Java 类库,而JRE又包括 JVM、类加载器、字节码校验器以及大量的基础类库。
JDK 安装路径下子目录作用如下:
1.3 Java 程序基本规则
- Java 程序是一种纯粹的面向对象的程序设计语言,Java 程序必须以类(class)的形式存在,类是 Java 最小的程序运行单位。Java 不允许可执行性语句、方法等独立存在,所有的程序部分都必须放到类定义里面。
- Java 程序源文件的后缀必须是
.java
;在通常情况下,Java 程序源文件的主文件名可以是任意的。如果 Java 程序源代码里定义了一个 public 类,则该源文件的主文件名必须与该 public 类的类名相同,也就是说一个 Java 源文件中最多定义一个 public 类。 - 文档注释是用于生成 API 文档的,而 API 文档主要用于说明类、方法、成员变量、构造器和内部类之前的注释,忽略其他地方的文档注,javadoc 默认只处理 public 或 protected 修饰的内容。文档注释以斜线后紧跟两个星号
/**
开始,以星号后紧跟一个斜线*/
结束,中间部分全部都是文档注释被提取到 API 文档中。
常用的 javadoc 标记如下:
@author:指定 Java 程序的作者
@version:指定源文件的版本
@deprecated:不推荐使用的方法
@param:方法的参数说明信息
@return:方法的返回值说明信息
@see:“参见”,用于指定交叉参考的内容
@exception:抛出异常的类型
@throws:抛出的异常,和 @exception 同义
生成 API 文档时加上-encoding utf-8 -charset utf-8 防止字符编码问题
位置 | 标记 |
---|---|
类或接口 | @see @deprecated @author @version |
方法或构造器 | @see @deprecated @param @return @throws @exception |
成员变量 | @see @deprecated |
二、Java 基础
2.1 关键字
Java中所有关键字都是小写的,TRUE、FALSE、NULL都不是 Java 关键字,但 Java 提供了三个特殊的直接量(literal):true
、false
和 null
;关键字受限即只在某些特定的场合有特殊含义,在其他情况下可以是标识符。注意 main
也不是关键字。
关键字 | 含义 | 关键字 | 含义 |
---|---|---|---|
abstract | 抽象类或方法 | assert | 用来查找内部程序错误 |
boolean | 布尔类型 | break | 跳出选择语句或循环 |
byte | 8位整数类型 | case | switch 的一个分支 |
catch | 捕获异常的 try 子句 | char | Unicode 字符类型 |
class | 定义一个类类型 | const | 未使用(保留字) |
continue | 在循环末尾继续 | default | switch 的默认子句 |
do | do/while 循环最前面的语句 | double | 双精度浮点数类型 |
else | if 语句的 else 子句 | enum | 枚举类型 |
exports | 导出一个模块的包(受限) | extends | 定义一个类的父类,或者 一个通配符的上界 |
final | 一个变量或一个不能被覆盖的类或方法 | finally | try 块中总会执行的部分 |
float | 单精度浮点类型 | for | 一种循环类型 |
goto | 未使用(保留字) | if | 一个条件语句 |
implements | 定义一个类是实现的接口 | import | 导入一个包 |
instanceof | 测试一个对象是否为一个类的实例 | int | 32位整数类型 |
interface | 一种抽象类型,其中包含可以由类实现的方法 | long | 64位长整数类型 |
native | 由宿主系统实现的一个方法 | new | 分配一个对象或数组 |
null | 一个空引用(技术上讲 null 是一个字面量,而不是关键字) | module | 声明一个模块(受限) |
open | 修改一个 module 声明(受限) | opens | 打开一个模块的包(受限) |
package | 包含类的一个包 | private | 这个特性只能由该类的方法访问 |
protected | 这个特性只能由该类、其子类以及同一个包中的其他类的方法访问 | provides | 指示一个模块使用一个服务(受限) |
public | 这个特性可以由所有类的方法访问 | return | 从一个方法返回 |
short | 16位整数类型 | static | 这个特性是类或接口特有的,而不属于类的实例 |
strictfp | 对浮点数计算使用严格的规则 | super | 超类对象或构造器、通配符的下界 |
switch | 一个选择语句 | synchronized | 对线程而言是原子的方法或代码块 |
this | 当前类的一个方法或构造器的隐含参数 | throw | 抛出一个异常 |
to | exports 或 opens 声明的一部分(受限) | throws | 一个方法可能抛出点的异常 |
transient | 标记非永久的数据 | transitive | 修饰一个 requires 声明(受限) |
try | 捕获异常的代码块 | uses | 指示一个模块使用一个服务(受限) |
var | 声明一个变量的类型是推导得出的(受限) | void | 指示一个方法不返回任何值 |
volatile | 确保一个字段可以由多个 线程访问 | with | 在一个 provides 语句中定义服务类(受限) |
while | 一种循环 |
2.2 命名规范
Java 语言的标识符必须以字母、下划线(_)、美元符($)开头,后面可以跟任意数字的字母、数字、下划线和美元符,区分大小写。
以下命名规范参考阿里巴巴 Java 开发手册:
- 代码中命名均不能以下划线或美元符开始或结束,严禁使用中文和英文混合,更不能直接使用中文的方式。
- 类名使用 UpperCamelCase 风格,单词以大写字母开头其他字母均为小写,如果由多个单词组成,则单词的第一个字母都应该大写,源代码的文件名必须与公共类的名字相同,例如
ForceCode
; - 方法名、参数名、成员变量、局部变量都统一使用 lowerCamelCase 风格,即第一个单词应以小写字母作为开头,后面的单词则用大写字母开头,例如
getHttpMessage()
; - 常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长,例如
MAX_STOCK_COUNT
; - 抽象类命名使用
Abstract
或Base
开头;异常类命名使用Exception
结尾;测试类命名以它要测试的类的名称开始,以Test
结尾; - 当要区别接口类和实现类的时候,可以在类的后面加上
impl
; - 类型与中括号紧挨相连来表示数组,例如
String[] args
; - 包名统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词。包名统一使用
单数形式,但是类名如果有复数含义,类名可以使用复数形式。 - 避免在子父类的成员变量之间、或者不同代码块的局部变量之间采用完全相同的命名,使可读性降低。
2.3 基本数据类型
Java 语言是强类型语言:
- 所有变量必须先声明后使用;
- 指定类型的变量只能接受类型与之匹配的值;
Java 语言支持的数据类型如下,整数型默认为 int,浮点型默认为 double:
2.3.1 整数类型
整数类型默认是 int 类型,Java整数有4种表示方式:十进制、八进制和十六进制,其中二进制的整数以 0b 或 0B 开头;八进制的整数以 0 开头;十六进制的整数以 0x 或 0X 开头,其中10 ~ 15 分别以 a ~ f(不区分大小写)表示。
- 如果直接将一个较小的整数值(在 byte 或者 short 类型的范围内)赋值给 byte 或 short 变量,系统会自动把这个整数值当成 byte 或者 short 处理,javac 编译器会自动隐含地补上(byte)、(short)、(char)。
- 如果使用一个超过 int 范围的整数值时,Java 不会自动将该整数当成 long 类型处理。long 类型数值通常增加 l 或 L 后缀。
- 计算机内所有的二进制都是以二进制形式存在,原码是直接讲一个数值换算成二进制,但计算机以补码的形式保存所有的整数。正数的补码与源码完全相同,负数的补码等于原码最高位(符号位)不变,其余位按位取反再加1。
- 数据范围与字节数不一定相关,例如float数据范围比long更加广泛,但是float是4字节,long是8字节。
注意:原码 -128 无法表示,Java 7 开始可以为数字字面量任意加_增加易读性。
(byte)0b1000_0000 = -128 0b1000_0000 = 128
(byte)0b0111_1111 = 127
(byte)0b1111_1111 = -1
//定义十六进制数赋值给 byte 变量,将输出17
byte bval1 = 0x11;
//注意:超过 int 范围将报错,而不是自动转换成 int
//long bignum = 9876543210;
long bignum = 9876543210L;
/*
定义一个8位的二进制整数,该数值默认占32位,正数
强制类型转换成byte时产生了溢出,导致变成负数
*/
byte bval2 = (byte)0b10000000;
System.out.println(bval2); //输出 -128
/*
定义一个32位二进制整数,最高位是1
但由于添加L后缀,整数实际上64位,32位的1不再是符号位
结果等于2的31次方
*/
long val = 0b1000_0000_0000_0000_0000_0000_0000_0000L;
System.out.println(val); //输出 2147483648,不加L输出-2147483648
2.3.2 字符类型
字符类型 char 常用于表示单个的字符,值必须用单引号('
)括起来,Java 语言使用16位的 Unicode 字符集作为编码方式。
字符型值有3种表示形式:
- 直接通过单个字符来指定字符型值,例如
'A'
; - 通过转义字符来表示特使字符型值,常用的转义字符有退格符
'\b'
,换行符'\n'
,回车符'\r'
,制表符'\t'
,双引号'\"'
,单引号'\''
,反斜线'\\'
; - 直接使用 Unicode 值来表示字符型值,格式是
\uXXXX
,其中 XXXX 代表十六进制数;
在Unicode 中,码点(code point)是指一个编码表中某个字符对应的代码值,采用十六进制书写,并加上前缀 U+,例如 U+0041 就是拉丁字母 A 的码点。Unicode 码点可以分为17个代码平面(code plane),第一个代码平面称为基本多语言平面(basic multilingual plane),包括码点从 U+0000 到 U+FFFF 的经典 Unicode 代码;其余16个平面的码点从 U+10000 到 U+10FFF,包括辅助字符(supplementary character)。
UTF-16 编码采用不同长度的编码表示所有 Unicode 码点,在基本多语言平面中,每个字符用16位表示,称为代码单元(code unit);而辅助字符编码为一对连续的代码单元。采用这中编码对表示的各个值落入基本多语言平面中未使用的 2048 个值范围中,通常称为替代区域(surrogate area)( U+D800 ~ U+DBFF用于第一个代码单元,U+DC00 ~ U+DFFF用于第二个代码单元)。
Java 中,char 类型描述了 UTF-16 编码中的一个代码单元。
/*
Unicode 转义序列会在解析代码之前处理
\u0022 会在解析之前转换成 “
下面将输出空格
*/
String str = "\u0022 + \u0022";
//小心代码注释中的 \u,下面会产生错误
//\u000A is a new line
//look inside c:\users
由于计算机底层保存该字符实际上是保存该字符对应的编号,因此 char 类型的值也可直接作为整数值使用,相当于保存一个16位的无符号整数,范围是 0 ~ 65535;
2.3.3 浮点类型
Java 的浮点类型有两种:float 和 double,表现形式有两种:十进制和科学计数法,默认类型为 double。浮点数只是一个近似值,并非精确的值。浮点数值不适用于无法接受舍入误差的金融计算,这种情况应该使用 BigDecimal 类。
Java 提供了三个特殊的浮点值:正无穷大、负无穷大和非数。正无穷大通过 Double 或 Float 类的POSITIVE_INFINITY
表示;负无穷大通过 Double 或 Float 类的NEGATIVE_INFINITY
表示,非数通过 Double 或 Float 类的 NaN
表示。所有的正无穷大都相等,负无穷大相等,NaN
不与任何数甚至自身相等,比较可以使用 Double.isNaN
判断。
正浮点数除以 0 得到正无穷大,负浮点数除以 0 得到负无穷大,0.0 除以 0.0 或 对一个负数开方将得到非数,求余浮点运算中除数为0也将得到非数。整数或0 / 0 则会抛出异常:java.lang.ArithmeticException: / by zero
总结:整数除以 0 将得到一个除法异常,而浮点数除以或求余 0 将得到无穷大或 NaN 结果。
2.3.4 布尔型
Java 语言中 boolean 类型的数值为 true或 false,不能用 0 或 非 0 来表示。
Java 并没有强制规定 boolean 类型的变量所占用的内存空间,虽然只需要1位即可保存,但大部分计算机允许分配的最小内存单元是字节(8位),因此 bit 大部分时间占用8位。
2.3.5 基本类型转换
- 自动类型转换(隐式)
注意:byte 类型不能自动类型转换成 char 类型;任何基本类型的值与字符串值进行连接运算(+
)时,基本类型的值将自动转换成字符串类型,因此可以将基本类型的值和空字符串进行连接转换成字符串。 - 强制类型转换(显式)
- 表达式类型的自动提升
- 所有的 byte 类型、short类型和 char 类型自动提升到 int 类型;
- 整个算术表达式的数据类型自动提升到与表达式中最高等级操作数相同的类型;特别的,两个 int 整数进行除法运算,即使无法除尽也将得到一个 int 类型的结果。
- 在给变量进行赋值的时候,如果右侧的表达式当中全都是常量,没有任何变量,那么编译器javac将会直接将若干个常量表达式计算得到结果;
short result = 5 + 8; // 等号右边全都是常量,没有任何变量参与运算
编译之后,得到的.class字节码文件当中short result = 13;这称为编译器的常量优化。但是一旦表达式中有变量参与,就没有这种优化了。
2.3.6 直接量
直接量通常只有三种类型:基本类型、字符串型和 null 类型。String 类型的直接量不能赋值给其他类型的变量;null 类型的直接量可以直接赋值给任何引用类型的变量,包括 String 类型,null 不能直接在控制台打印,需要与空字符串连接;boolean 类型的直接量只能赋值给 boolean 类型的变量。
常量池:指的是在编译期间确定,并保存在已经编译的
.class
文件中一些数据。包括类、方法、接口中的常量、字符串常量。
2.4 运算符
运算符是一种特殊的符号,用于数据的运算、赋值和比较等。
2.4.1 算术运算符
算术运算符 | 功能 |
---|---|
+ | 加法运算符或字符串的连接运算符 |
- | 减法运算符 |
* | 乘法运算符 |
/ | 除法运算符 |
% | 求余运算符 |
++ | 自加 |
– | 自减 |
2.4.2 赋值运算符
注意:赋值运算符的左值只能是变量。
2.4.3 位运算符
位运算符 | 功能 |
---|---|
& | 按位与 |
| | 按位或 |
~ | 按位非 |
^ | 按位异或 |
<< | 左移运算符 |
>> | 右移运算符(右移补符号位) |
>>> | 无符号右移运算符(右移补0) |
一般来说,位运算符只能操作整数类型的变量或值。且遵循以下规则:
- 对于低于 int 类型的操作数总是先自动类型转换成 int 再移位;
- 对于 int 类型的整数移位 a >> b,系统先用 b 对 32 求余,同理 long 类型对 64 求余。
2.4.4 比较运算符
比较运算符用于判断两个变量或常量的大小,比较运算的结果是一个 boolean 值。
比较运算符 | 功能 |
---|---|
> | 大于,两个操作数为数值类型 |
>= | 大于等于,两个操作数为数值类型 |
< | 小于,两个操作数为数值类型 |
<= | 小于等于,两个操作数为数值类型 |
== | 不同数值类型数值相等的返回true;具有父子关系的引用类型相等返回true;boolean 类型相同返回true |
!= | 同上 |
2.4.5 逻辑运算符
逻辑运算符用于操作两个 boolean 类型变量或常量。
逻辑运算符 | 功能 |
---|---|
&& | 与 |
& | 不短路与 |
|| | 或 |
| | 不短路或 |
! | 非 |
^ | 异或 |
2.4.6 三目运算符
(expression) ? if-true-statement : if-false-statement;
2.4.7 运算符的结合性和优先级
Java 中大部分运算符是从左向右结合的,只有单目运算符、赋值运算符和三木运算符是从右到左结合的。
运算符说明 | 运算符 | 结合性 |
---|---|---|
分隔符 | . [] () {} , ; | 从左向右 |
单目运算符 | ++ – ~ | 从右向左 |
强制类型转换 | () | 从右向左 |
乘除法求余 | * / % | 从左向右 |
加法/减法 | + - | 从左向右 |
移位运算符 | << >> >>> | 从左向右 |
关系运算符 | < <= >= > instanceof | 从左向右 |
等价运算符 | == != | 从左向右 |
按位与 | & | 从左向右 |
按位异或 | ^ | 从左向右 |
按位或 | | | 从左向右 |
逻辑与 | && | 从左向右 |
逻辑或 | || | 从左向右 |
三木运算符 | ?: | 从右向左 |
赋值 | = += -= *= /= &= |= ^= %= <<= >>= >>>= | 从右向左 |
三、流程控制与数组
Java 提供了两种基本的流程控制结构:分支结构和循环结构。其中分支结构用于实现根据条件来选择性地执行某段代码,循环结构则用于实现根据循环条件重读执行某段代码。
3.1 流程控制
3.1.1 顺序结构
顺序结构就是程序从上到下逐行执行,中间没有任何判断和跳转。
3.1.2 分支结构
if
条件语句
if(condition1)
statement1
else if(condition2)
statement2
else
statement3
switch
分支语句是一个控制表达式和多个 case 标签组成,switch 语句后面的控制表达式的数据类型只能是 byte、short、char、int 四种整数类型,枚举类型和 java.lang.String 类型(Java 7)。
switch的运行流程:先求出 expression 表达式的值,然后拿这个表达式和 case 标签后的值进行比较,一旦遇到相等的值,程序就开始运行这个 case 标签后的代码,不再判断与后面 case、default 标签是否匹配,除非遇到 break 才会结束。所以大多数情况下 case 标签后的每个代码块都有一个break 语句。
switch(expression)
{
case condition1:
{
statement
break;
}
case condition2:
{
statement
break;
}
default:
{
statement
}
}
switch 语句注意事项:
- 多个 case 后面的数值不可以重复;
- switch 后面小括号中只能是byte/char/short/int、字符串和枚举类型;
- 一旦匹配到相应的 case,不再判断后面的 case 是否匹配,直到遇到 break 或 语句整体结束时结束。
3.1.3 循环结构
while
循环语句do while
循环语句for
循环语句
for 循环允许同时指定多个初始化语句,但变量应该具有想同类型;循环条件允许包含逻辑运算符的表达式。
- 嵌套循环
3.1.4 控制循环结构
break
结束循环:break 语句不仅可以结束其所在的循环,还可以直接结束其外层循环。此时需要在 break 后紧跟一个标签用于标识循环。Java 中标签就是一个紧跟着英文冒号的标识符,且 Java 中标签只有放在循环语句之前才有作用;
public static void main(String[] args) {
outer:
for(int i = 0; i < 5; i++)
{
//内层循环
for(int j = 0; j < 3; j++)
{
System.out.println("i 的值为" + i + " j 的值为" + j);
if(j == 1)
//跳出 outer 标签所标识的循环
break outer;
}
}
}
continue
忽略本次循环剩下的语句和直接跳过标签所标识循环的当次循环的剩下语句;return
结束方法;
3.2 数组类型
Java 的数组也是一种数据类型(引用类型),要求所有的数组元素具有相同的数据类型。数组的初始化有两种方式:
- 静态初始化:初始化时由程序员显式指定每个数组元素的初始值,由系统决定数组长度;执行静态初始化时,显式指定的数组元素值的类型必须与 new 关键字后的 type 相同,或者是其子类的实例。
//静态初始化
type[ ] arrayName = new type[ ]{ element1,element2,element3,…… }
//静态初始化的简化写法
type[ ] arrayName = { element1,element2,element3,…… }
静态初始化也有默认值的过程,不过系统马上将默认值替换为大括号中的指定值。
- 动态初始化:动态初始化只指定数组的长度,由系统为每个数组元素指定初始值。type 同样必须与定义数组时使用的 type 类型相同,或者是定义数组时使用的 type 类型的子类。
//数组的定义和初始化同时完成,使用动态初始化语法
type[ ] arrayName = new type[length]
数组元素类型 | 初始化元素值 |
---|---|
整型(byte、short、int、long) | 0 |
浮点型(float、double) | 0.0 |
字符型(char) | ‘\u0000’ |
布尔型(boolean) | false |
引用类型(类、接口和数组) | null |
foreach 循环:自动遍历数组和集合的每个元素。variableName 为形参,保存了数组元素的值,通常不要对循环变量进行赋值,这样并不能改变数组元素的值。array | collection 必须是一个数组或者是一个实现了 Iterable 接口的类对象(例如 ArrayList)。
for(type variableName : array | collection)
{
//variableName 自动迭代访问每个元素
}
二维数组的实质仍然是一维数组,只是其数组元素也是指向一维数组的引用,所以 arrName.length 返回一维长度,其定义为:
type[][] arrName = new type[length][ ];
//使用静态初始化语法来初始化一个二维数组
String[][] str = {new String[3], new String[]{"hello"}};
3.3 Arrays 类
Java 提供的 Arrays 类包含的方法可以操作数组,具体请查阅 API 文档。
方法 | 使用说明 |
---|---|
int binarySearch(type[] a, type key) | 使用二分法查询key 元素值在数组a中出现的索引;如果a数组不包含key 元素值,则返回负数,调用该方法时要求数组中元素已经按升序排列。 |
int binarySearch(type[] a, int fromIndex, int toIndex, type key) | 二分法搜索a 数组中fromIndex 到toIndex 索引的元素,调用该方法时要求数组中元素已经按升序排列。 |
type[] copyOf(type[] original, int length) | 该方法将把original 数组复制成一个新数组,其中length是新数组的长度。如果length 小于original 数组的长度,则新数组就是原数组的前面length 个元素,如果length 大于original 数组的长度,则新数组的前面元素就是原数组的所有元素,后面补充 0 、false、null。 |
type[] copyOfRange(type[] original, int from, int to) | 只复制数组original 的from 索引到to 索引的元素。 |
boolean equals(type[] a1, type[] a2) | 如果a1 数组和a2 数组的长度相等,而且他们的数组元素也一一相同,该方法将返回true。 |
void fill(type[] a, type val) | 该方法将会a 数组里的所有元素赋值为val 。 |
void fill(type[] a, int fromIndex, int toIndex, type val) | 该方法仅仅将a 数组的fromIndex 到toIndex 索引的数组元素赋值为val 。 |
void sort(type[] a) | 该方法对数组a 的数组元素进行排序。 |
void sort(type[] a,int fromIndex,int toIndex) | 该方法仅仅将a 数组的fromIndex 到toIndex 索引的数组元素进行排序。 |
String toString(type[] a) | 该方法将一个数组转换成一个字符串。该方法按顺序把多个数组元素连缀在一起,多个数组元素使用英文逗号和空格隔开。 |
下面是Java 8为 Arrays 类增强的工具方法:
方法 | 使用说明 |
---|---|
void parallelPrefix(xxx[] array, XxxBinaryOperator op) | 该方法使用op 参数指定的计算公式计算得到的结果作为新的元素。op 计算公式包括left 、right 两个形参,其中left 代表数组中前一个索引处的元素,right 代表数组中当前索引处的元素,当计算第一个新数组元素时,left 的值默认为1。 |
void parallelPrefix(xxx[] array, int fromIndex, int toIndex, XxxBinaryOperator op) | 与上一个方法的区别:该方法仅重新计算fromIndex 到toIndex 索引的元素。 |
void setAll(xxx[] array, IntToXxxFunction generator) | 该方法使用指定的生成器(generator) 为所有数组元素设置值,该生成器控制数组元素的值得生成算法。 |
void parallelSetAll(xxx[] array, IntToXxxFunction generator) | 该方法增加了并行能力,利用多CPU并行来提高性能。 |
void parallelSort(xxx[] a) | 该方法与 Arrays 类以前就有的sort() 方法相似,只是该方法增加了并行能力,利用多CPU并行来提高性能。 |
void parallelSort(xxx[] a, int fromIndex, int toIndex) | 该方法只对fromIndex 到toIndex 索引的元素进行排序。 |
Spliterator.OfXxx.spliterator(xxx[] array) | 将该数组的所有元素转换成对应的Spliterator 对象。 |
Spliterator.OfXxx.spliterator(xxx[] array, int startInclusive,int endExclusive) | 该方法仅转换startInclusive 到endExclusive 索引的元素。 |
XxxStream stream(xxx[] array) | 该方法将数组转换为Stream ,Stream 是Java 8的新增的流式编程的API。 |
XxxStream stream(xxx[] array, int startInclusive,int endExclusive) | 该方法与上一个方法类似,区别是该方法仅将startInclusive 到endExclusive 索引的元素转换为Stream 。 |
所有以parallel
开头的方法都表示该方法可利用 CPU 并行的能力来提高性能。xxx 代表不同的数据类型,比如处理 int[] 型数组时应将 xxx 换成 int。
JVM 内存划分:
区域名称 | 作用 |
---|---|
栈(Stack) | 存放的都是方法中的局部变量,方法的运行一定要在栈中进行 |
堆(Heap) | 存储对象或数组,new 创建的都存储在堆内存中,堆内存中的东西都有16进制地址值,数据都有默认值 |
方法区(Methods Areas) | 存储 class 相关信息,包含方法的信息 |
本地方法栈(Native Methods Stack) | 存储可以运行的 class 文件,包含方法的信息 |
寄存器(pc Register) | cpu相关 |