Java 的基本程序设计结构
2.1 一个简单的 Java 应用程序
- 一个最简单的 Java 应用程序,它只发送一条消息到控制台窗口中:
/** * This is the first sample program in Core Java Chapter 3 * @version 1.01 1997-03-22 * @author Gary Cornell */ public class FirstSample { public static void main(String[] args) { System.out.println("We will not use 'Hello, World!'"); } }
- 首先,Java 区分大小写。如果出现了大小写拼写错误(例如,将 main 拼写成 Main),程序将无法运行。
- 关键字 public 称为访问修饰符 (access modifier),这些修饰符用于控制程序的其他部分对这段代码的访问级别。
- 关键字 class 表明 Java 程序中的全部内容都包含在类中。
- 关键字 class 后面紧跟类名。
- Java 中定义类名的规则很宽松。
- 名字必须以字母开头,后面可以跟字母和数字的任意组合。
- 长度基本上没有限制,但是不能使用 Java 保留字。
- 标准的命名规范为(类名 FirstSample 就遴循了这个规范):类名是以大写字母开头的名词,如果名字由多个单词组成,每个单词的第一个字母都应该大写(这种在一个单词中间使
用大写字母的方式称为骆驼命名法 (camel case)。
- 源代码的文件名必须与公共类的名字相同,并用 .java 作为扩展名。
- 在 Java 中, 每个句子必须用分号结束,特别需要说明,回车不是语句的结束标志,因此,如果需要可以将一条语句写在多行上。
- Java 中的方法可以没有参数,也可以有一个或多个参数(有的程序员把参数叫做实参),即使一个方法没有参数,也需要使用空括号。
2.2 注释
- 在 Java 中,有 3 种标记注释的方式。最常用的方式是使用 //,其注释内容从 // 开始到本行结尾。
- 当需要更长的注释时,既可以在每行的注释前面标记 //,也可以使用 /* 和 */ 注释界定符将一段比较长的注释括起来。
- 最后,第 3 种注释可以用来自动地生成文档。这种注释以 /** 开始,以 **/ 结束。
在 Java 中,/* 和 */ 注释不能嵌套,也就是说,不能简单地把代码用 / 和 */ 括起来作为注释,因为这段代码本身可能也包含一个 */ 界定符。
2.3 数据类型
- Java 是一种强类型语言。
- 这就意味着必须为每一个变量声明一种类型。
- 在 Java 中,共有 8 种基本类型 (primitive type),其中有 4 种整型、2 种浮点类型、1 种字符类型 char(用于表示 Unicode 编码的代码单元)和 1 种用于表示真值的 boolean 类型。
2.3.1 整型
- 整型用于表示没有小数部分的数值,允许是负数。
- Java 提供了 4 种整型:int、short、long、byte。
- 在通常情况下, int 类型最常用。
- 如果想要表示整个地球的居住人口,就需要使用 long 类型了。
- byte 和 short 类型主要用于特定的应用场合,例如,底层的文件处理或者存储空间很宝贵时的大数组。
2.3.2 浮点类型
- 浮点类型用千表示有小数部分的数值。
- 在 Java 中有两种浮点类型:float、double。
- double 表示这种类型的数值精度是 float 类型的两倍(双精度数值)。
- 在很多情况下,float 类型的精度 (6 ~ 7 位有效数字)并不能满足需求。
- 实际上,只有很少的情况适合使用 float 类型,例如,需要单精度数的库,或者需要存储大量数据时。
- float 类型的数值有一个后缀 F 或 f (例如,3.14F)。
- 没有后缀 F 的浮点数值(如 3.14) 总是默认为 double 类型。
- 当然,也可以在浮点数值后面添加后缀 D 或 d。
2.3.3 char 类型
- char 类型原本用于表示单个字符。
- 不过,现在情况已经有所变化。
- 如今,有些 Unicode 字符可以用一个 char 值描述,另外一些 Unicode 字符则需要两个 char 值。
- char 类型的字面量值要用单引号括起来。
- 例如:’ A ’ 是编码值为 65 的 字符常量。
- 它与 “A” 不同,“A” 是包含一个字符 A 的字符串。
- char 类型的值可以表示为十六进制值,其范围从 \u0000 到 \uFFFF。
- 在 Java 中,char 类型描述了 UTF-16 编码中的一个代码单元。
- 强烈建议不要在程序中使用 char 类型, 除非确实需要处理 UTF-16 代码单元。
- 最好将字符串作为抽象数据类型处理。
2.3.4 boolean 类型
- boolean (布尔)类型有两个值:false 和 true,用来判定逻辑条件,整型值和布尔值之间不能进行相互转换。
2.4 变量与常量
2.4.1 声明变量
- 在 Java 中,每个变量都有一个类型 (type)。
- 在声明变量时,先指定变量的类型,然后是变量名。
- 每个声明都以分号结束。
- 变量名必须是一个 以字母开头并由字母或数字构成的序列。
- 变量名中所有的字符都是有意义的,并且大小写敏感。
- 变量名的长度基本上没有限制。
- 不能使用 Java 保留字作为变量名。
- 可以在一行中声明多个变量,不过,不提倡使用这种风格,逐一声明每一个变量可以提高程序的可读性。
2.4.2 变量初始化
- 声明一个变量之后,必须用赋值语句对变量进行显式初始化,千万不要使用未初始化的变量的值。
- 要想对一个已经声明过的变量进行赋值,就需要将变量名放在等号(=)左侧,再把一个适当取值的 Java 表达式放在等号的右侧。
- 也可以将变量的声明和初始化放在同一行中。
- 在 Java 中可以将声明放在代码中的任何地方,但是变量的声明最好尽可能地靠近变量第一次使用的地方,这是一种良好的程序编写风格 。
- 从 Java 10 开始,对于局部变量,如果可以从变量的初始值推断出它的类型,就不再需要声明类型,只需要使用关键宇 var 而无须指定类型。
var vacationDays = 12; // vacationDays is an int var greeting = "Hello"; // greeting is a String
2.4.3 常量
- 在 Java 中,利用关键字 final 指示常量。
- 关键字 final 表示这个变量只能被赋值一次。
- 一旦被赋值之后 ,就不能够再更改了。
- 习惯上,常量名使用全大写。
- 在 Java 中,经常希望某个常数可以在一个类的多个方法中使用,通常将这些常量称为类常量 (class constant),可以使用关键字 static final 设置一个类常量。
- 类常量的定义位千 main 方法的外部。
- 因此,在同一个类 的其他方法中也可以使用这个常量。
- 如果一个常量被声明为 public, 那么其他类的方法也可以使用这个常量。
2.4.4 枚举类型
- 有时候,变量的取值只在一个有限的集合内。
- 针对这种情况,可以自定义枚举类型。
- 枚举类型包括有限个命名的值。
- 例如,
enum Size { SMALL, MEDIUM, LARGE, EXTRA_LARGE };
- 现在,可以声明这种类型的变量:
Sizes= Size.MEDIUM;
- size 类型的变量只能存储这个类型声明中给定的某个枚举值,或者特殊值 null, null 表示这个变量没有设置任何值。
2.5 运算符
2.5.1 算术运算符
- 运算符用于连接值。
- 在 Java 中,使用算术运算符 +、-、*、/ 表示加、减、乘、除运算。
- 当参与除法运算的两个操作数都是整数时,表示整数除法;否则,表示浮点除法。
- 整数的求余操作(取模)用 % 表示。
- 整数被 0 除将会产生一个异常,而浮点数被 0 除将会得到无穷大或 NaN 结果。
2.5.2 数学函数与常量
- 在 Math 类 中,包含了各种各样的数学函数。
- 要想计算一个数值的平方根,可以使用 sqrt 方法:
double x = 4; double y = Math.sqrt(x); System.out .println(y); // prints 2.0
- 在 Java 中,没有幕运算,因此需要借助于 Math 类的 pow 方法 。
- 以下语句:
double y = Math.pow(x, a);
将 y 的值设置为 x 的 a 次幕。 - pow 方法有两个 double 类型的参数 ,其返回结果也为 double 类型。
- 以下语句:
2.5.3 数值类型之间的转换
- 当用一个二元运算符连接两个值时(例如 n + f, n 是整数,f 是浮点数),先要将两个操作数转换为同一种类型,然后再进行计算。
- 如果两个操作数中有一个是 double 类型,另 一个操作数就会转换为 double 类型。
- 否则,如果其中一个操作数是 float 类型,另一个操作数将会转换为 float 类型。
- 否则,如果其中一个操作数是 long 类型,另一个操作数将会转换为 long 类型。
- 否则,两个操作数都将被转换为 int 类型。
- 强制类型转换
- int 类型的值将会自动地转换为 double 类型。
- 但另一方面,有时也需要将 double 转换成 int。
- 在 Java 中,允许进行这种数值之间的类型转换,当然,有可能会丢失一些信息。
- 这种可能损失信息的转换要通过强制类型转换 (cast) 来完成。
- 强制类型转换的语法格式是在圆括号中给出想要转换的目标类型,后面紧跟待转换的变量名。
double x = 9.997; int nx = (int ) x;
- 这样,变量 nx 的值为 9,因为强制类型转换通过截断小数部分将浮点值转换为整型。
- 如果想对浮点数进行舍入运算,以便得到最接近的整数(在很多情况下,这种操作更有用),那就需要使用 Math. round 方法:
double x = 9.997; int nx = (int) Math .round(x);
- 现在,变量 nx 的值为 10。
- 当调用 round 的时候,仍然需要使用强制类型转换 (int) 。
- 其原因是 round 方法返回的结果为 long 类型,由于存在信息丢失的可能性,所以只有使用显式的强制类型转换才能够将 long 类型转换成 int 类型。
2.5.4 结合赋值和运算符
- 可以在赋值中使用二元运算符,这是一种很方便的简写形式。
- 例如 x += 4; 等价于 x = x + 4;
- 如果运算符得到一个值,其类型与左侧操作数的类型不同,就会发生强制类型转换。
- 自增与自减运算符
- n++ 将变量 n 的 当前值加 1,n- - 则将 n 的值减 1。
- 由于这些运算符改变的是变量的值,所以它们不能应用于数值本身。
- 还有一种“前缀”形式:++n。
- 后缀和前缀形式都会使变量值加 1 或减 1。
- 前缀形式会先完成加 1,而后缀形式会使用变量原来的值。
2.5.5 关系和 boolean 运算符
- 要检测相等性,可以使用两个等号 ==。
- 可以使用 != 检测不相等。
- 还有经常使用的 <(小于)、>(大于)、<=(小于等于)和 >=(大于等于)运算符。
- Java 沿用了C++ 的做法,使用 && 表示逻辑”与“运算符,使用 || 表示逻辑”或“运算符。
- 感叹号 ! 就是逻辑非运算符。
- && 和 || 运算符是按照“短路”方式来求值的:如果第一个操作数已经能够确定表达式的值,第二个操作数就不必计算了。
- Java 支持三元操作符 ? :
condition ? expression1 : expression2
,如果条件为 true,就为第一个表达式的值,否则计算为第二个表达式的值。
2.5.6 位运算符
- 处理整型类型时,可以直接对组成整数的各个位完成操作。
- 这意味着可以使用掩码技术得到整数中的各个位。
- 位运算符包括:&(“and”),(“or”),^(“xor”) ,~(“not”)。
- &和 I 运算符不采用“短路”方式来求值,也就是说,得到计算结果之前两个操作数都需要计算。
- “>>” 和 “<<” 运算符可以将位模式左移或右移。
- “>>>” 运算符会用 0 填充高位,它会用符号位填充高位,不存在 “<<<” 运算符。
2.5.7 括号与运算符级别
- 运算符优先级
- 如果不使用圆括号,就按照给出的运算符优先级次序进行计算。
- 同一个级别的运算符按照从左到右的次序进行计算(但右结合运算符除外)。
- 与 C 或 C++ 不同,Java 不使用逗号运算符。
2.6 字符串
- Java 没有内置的字符串类型,而是在标准 Java 类库中提供了 一个预定义类 String,每个用双引号括起来的字符串都是 String 类的一个实例。
2.6.1 子串和字符串拼接
- String 类的 substring 方法可以从一个较大的字符串提取出一个子串。
- 类似于 C 和 C++,Java 字符串中的代码单元和代码点从 0 开始计数。
- substring 方法的第二个参数是不想复制的第一个位置。
- substring 的工作方式有一个优点:容易计算子串的长度。
- 字符串 s. substring (a, b) 的长度为 b - a。
- Java 语言允许使用 + 号连接(拼接)两个字符串。
- 当将一个字符串与一个非字符串的值进行拼接时,后者会转换成字符串。
- 如果需要把多个字符串放在一起,用一个界定符分隔,可以使用静态 join 方法:
// all is the string "S / M/ L/ XL" String all= String. join("/ ", "S", "M", "L", "XL");
- 在 Java 11 中, 还提供了一个 repeat 方法 :
// repeated is "JavaJavaJava" String repeated = "Java".repeat(3);
- String 类对象称为是不可变的 (immutable),编译器可以让字符串共享。
2.6.2 检测字符串是否相等
- 可以使用 equals 方法检测两个字符串是否相等。
- 如果字符串 s 与字符串 t 相等,则返回 true;
- 否则,返回 false 。
- s 与 t 可以是字符串变量,也可以是字符串字面量。
- 要想检测两个字符串是否相等,而不区分大小写,可以使用 equalslgnoreCase 方法。
- 一定不要使用==运算符检测两个字符串是否相等!
- 这个运算符只能够确定两个字符串是否存放在同一个位置上。
- 当然,如果字符串在同一个位置上,它们必然相等。
- 但是,完全有可能将内容相同的多个字符串副本放置在不同的位置上。
- 空串” “ 是长度为 0 的字符串。
- 空串是一个 Java 对象,有自己的串长度 (0) 和内容(空)。
- String 变量还可以存放一个特殊的值,名为 null,表示目前没有任何对象与该变量关联。
- length 方法将返回采用 UTF-16 编码表示给定字符串所需要的代码单元数量。
- 调用 s.charAt(n) 将返回位置 n 的代码单元, n 介于 0 ~ s .length() -1 之间。
2.6.3 String API
- char charAt(int index)
- 返回给定位置的代码单元。
- int compareTo(String other)
- 按照字典顺序,如果字符串位于 other 之前,返回一个负数;
- 如果字符串位于 other 之后,返回一个正数;
- 如果两个字符串相等,返回 0。
- boolean blank()
- 如果字符串为空或者由空格组成,返回 true。
- boolean equals(Object other)
- 如果字符串与 other 相等, 返回 true。
- boolean equalslgnoreCase(String other)
- 如果字符串与 other 相等(忽略大小写),返回 true。
- int indexOf (String str, int fromlndex)
- 返回与字符串 str 匹配的第一个子串的开始位置。
- 从索引 0 或 fromlndex 开始匹配,无 formIndex 参数默认为 0。
- 如果在原始字符串中不存在 str,则返回 -1。
- int lastindexOf (String str, int fromIndex)
- 返回与字符串 str 匹配的最后一个子串的开始位置。
- 从原始字符串末尾或 frornlndex 开始匹配。
- int length()
- 返回字符串代码单元的个数。
- String replace(CharSequence oldString, CharSequence newString)
- 返回一个新字符串。
- 这个字符串用 newString 代替原始字符串中所有的 oldString。
- 可以用 String 或 StringBuilder 对象作为 CharSequence 参数。
- String substring (int beginIndex, int endIndex)
- 返回一个新字符串。
- 这个字符串包含原始字符串中从 beginIndex 到 endlndex-1 的所有代码单元。
- String tolowerCase()/String toUpperCase()
- 返回一个新字符串。
- 这个字符串将原始字符串中的大写字母改为小写,或者将原始字符串中的所有小写字母改成大写字母。
- String trim()/String strip()
- 返回一个新字符串。
- 这个字符串将删除原始字符串头部和尾部小于等千 U+0020 的字符 (trim) 或空格 (strip)。
- String join(CharSequence delimiter, CharSequence…elements)
- 返回一个新字符串,用给定的定界符连接所有元素。
- String repeat (int count)
- 返回一个字符串,将当前字符串重复 count 次。
2.6.4 构建字符串
- 有些时候,需要由较短的字符串构建字符串。
- 如果采用字符串拼接的方式来达到这个目的,效率会比较低。
- 每次拼接字符串时 ,都会构建一个新的 String 对象,既耗时又浪费空间。
- 使用 StringBuilder 类就可以避免这个问题的发生。
- 如果需要用许多小段的字符串来构建一个字符串,那么应该按照下列步骤进行。
- 首先,构建一个空的字符串构建器:
StringBuilder builder= new StringBuilder();
- 当每次需要添加一部分内容时,就调用 append 方法。
- 在字符串构建完成时就调用 toString 方法,将可以得到一个 String 对象,其中包含了构建器中的字符序列。
- 首先,构建一个空的字符串构建器:
- StringBuilder 类在 Java 5 中引入 。 这个类的前身是 StringBuffer,它的效率稍有些低,但允许采用多线程的方式添加或删除宇符。如果所有字符串编辑操作都在单个线程中执行(通常都是这样),则应该使用 StringBuilder。
- StringBuilder insert(int offset, String str):在 offset 位置插入一个字符串并返回 this。
- StringBuilder delete(int startindex, int endindex):删除偏移量从 startindex 到 endindex -1 的代码单元并返回 this。
- StringBuilder toString():返回一个与构建器或缓冲器内容相同的字符串。
- StringBuilder append (String str):追加一个字符串并返回 this。
2.7 输入与输出
2.7.1 读取输入
- 要想通过控制台进行输入,首先需要构造一个与“标准输入流" System.in 关联的 Scanner 对象:
Scanner in = new Scanner(System.in);
- 现在,就可以使用 Scanner 类的各种方法读取输入了。
- 例如,nextline 方法将读取一行输入:
String name = in.nextLine();
- 使用 nextline 方法是因为在输入行中有可能包含空格。
- 要想读取一个单词(以空白符作为分隔符),可以调用:
String firstName = in.next();
- 要想读取一个整数,就调用 nextlnt 方法:
int age = in.nextInt();
- 要想读取下一个浮点数,就调用 nextDouble 方法。
- 例如,nextline 方法将读取一行输入:
2.7.2 格式化输出
- Java 5 沿用了 C 语言函数库中的 printf 方法。
- 例如,调用
System.out. printf("%8.2f", x);
会以 一个字段宽度 (field width) 打印 x 这包括 8 个字符,另外精度为小数点后 2 个字符。 - 可以为 printf 提供多个参数,例如:
System.out.printf("Hello, %s. Next year, you'll be %d", name, age);
- 例如,调用
- 每一个以 % 字符开始的格式说明符都用相应的参数替换。
- 格式说明符尾部的转换符指示要格式化的数值的类型;
- f 表示浮点数,s 表示字符串, d 表示十进制整数。
- 可以使用静态的 String.format 方法创建一个格式化的字符串,而不打印输出:
String message= String.format( "Hello, %s. Next year, you'll be %d", name, age);
2.7.3 文件输入与输出
- 要想读取一个文件,需要构造一个 Scanner 对象,如下所示:
Scanner in= new Scanner(Path.of("myfile.txt"), StandardCharsets.UTF_B);
- 如果文件名中包含反斜杠符号,就要记住在每个反斜杠之前再加一个额外的反斜杠转义:
"c:\\mydirectory\\myfile.txt"
。 - 在这里指定了 UTF-8 宇符编码,这对于互联网上的文件很常见(不过并不是普遍适用)。
- 读取一个文本文件时,要知道它的宇符编码,如果省略宇符编码,则会使用运行这个 Java 程序的机器的"默认编码”。
- 这不是一个好主意,如果在不同的机器上运行这个程序,可能会有不同的表现。
- 如果文件名中包含反斜杠符号,就要记住在每个反斜杠之前再加一个额外的反斜杠转义:
- 要想写入文件,就需要构造一个 PrintWriter 对象。
- 在构造器 (constructor) 中,需要提供文件名和字符编码:
PrintWriter out = new PrintWriter("myfile.txt", StandardCharsets.UTF_B);
- 如果文件不存在,创建该文件。
- 可以像输出到 System.out 一样使用 print、println 以及 printf 命令。
- Scanner(Path p, String encoding)
- 构造一个使用给定字符编码从给定路径读取数据的 Scanner。
- Scanner(String data)
- 构造一个从给定字符串读取数据的 Scanner。
- PrintWriter(String fileName)
- 构造一个将数据写入文件的 PrintWriter。
- 文件名由参数指定。
- static Path of(String pathname)
- 根据给定的路径名构造一个 Path。
2.8 控制流程
- 与任何程序设计语言一样,Java 使用条件语句和循环结构确定控制流程。
- 当需要对某个表达式的多个值进行检测时,可以使用 switch 语句。
- 块(即复合语句)是指由若干条 Java 语句组成的语句,并用一对大括号括起来。
- 块确定了变量的作用域。
- 一个块可以嵌套在另一个块中。
- 不能在嵌套的两个块中声明同名的变量。
2.8.1 条件语句
- 在 Java 中,一般的条件语句如下所示:
if (condition) statement1 else statement2;
- else 部分总是可选的。
- else 子句与最邻近的 if 构成一组。
- 反复使用 if… else if . … 很常见。
2.8.2 循环
- 当条件为 true 时, while 循环执行一条语句(也可以是一个块语句)。
- 一般形式如下:
while (condition) statement;
- 如果开始时循环条件的值就为 false, 那么 while 循环一次也不执行。
- 一般形式如下:
- 如果希望循环体至少执行一 次,需要使用 do/while 循环将检测 放在最后。
- 它的语法如下:
do statement while (condition);
- 这种循环语句先执行语句(通常是一个语句块),然后再检测循环条件。
- 如果为 true, 就重复执行语句,然后再次检测循环条件,以此类推。
- for 循环语句是支持迭代的一种通用结构,由一个计数器或类似的变量控制迭代次数,每次迭代后这个变量将会更新。
- for 语句的第 1 部分通常是对计数器初始化;
- 第 2 部分给出每次新一轮循环执行前要检测的循环条件;
- 第 3 部分指定如何更新计数器。
- 特别指出,如果在 for 语句内部定义一个变量,这个变量就不能在循环体之外使用。因此,如果希望在 for 循环体之外使用循环计数器的最终值,就要确保这个变量在循环之外声明。
2.8.3 多重选择 switch 语句
- 在处理多个选项时,Java 有一个与 CIC++ 完全一样的 switch 语句。
- switch 语句将从与选项值相匹配的 case 标签开始执行,直到遇到 break 语句,或者执行到 switch 语句的结束处为止。
- 如果没有相匹配的 case 标签,而有 default 子句,就执行这个
子句。
- 有可能触发多个 case 分支。
- 如果在 case 分支语句的末尾没有 break 语句,那么就会接着执行下一个 case 分支语句。
- 这种情况相当危险,常常会引发错误。
- case 标签可以是:
- 类型为 char、 byte、 short 或 int 的常量表达式。
- 枚举常量。
- 字符串字面量。
- 与用于退出 switch 语句的 break 语句一样,它也可以用于退出循环语句。
- continue 语句将中断正常的控制流程,并将控制转移到最内层循环的首部。
- 如果将 continue 语句用千 for 循环中,就可以跳到如循环的”更新”部分。
2.9 大数
- 如果基本的整数和浮点数精度不能够满足需求,那么可以使用 java.math 包中两个很有用的类:Biglnteger 和 BigDecimal。
- 这两个类可以处理包含任意长度数字序列的数值。
- Biglnteger 类实现任意精度的整数运算,BigDecimal 实现任意精度的浮点数运算。
- 不能使用人们熟悉的算术运算符(+和 *)处理大数,而需要使用大数类中的 add 和 multiply 方法。
2.10 数组
2.10.1 声明和访问数组
- 数组存储相同类型值的序列。
- 数组是一种数据结构,用来存储同一类型值的集合。
- 通过一个整型下标 (index, 或称索引)可以访问数组中的每一个值。
- 在声明数组变量时,需要指出数组类型(数据元素类型紧跟 [])和数组变量的名字:
int[] a;
- 不过,这条语句只声明了变量 a,并没有将 a 初始化为一个真正的数组。
- 应该使用 new 操作符创建数组:
int[] a= new int[100]; // or var a= new int[100] ;
,这条语句声明并初始化了一个可以存储 100 个整数的数组。
- 一旦创建了数组,就不能再改变它的长度,如果程序运行中需要经常扩展数组的大小,就应该使用数组列表(arraylist)。
- 在 Java 中,提供了一种创建数组对象并同时提供初始值的简写形式:
int[] smallPrimes = { 2, 3, 5, 7, 11, 13 };
- 这个语法中不需要使用 new, 甚至不用指定长度。
- 还可以声明一个匿名数组:
new int[] { 17, 19, 23, 29, 31, 37 }
- 这会分配一个新数组并填入大括号中提供的值。
- 它会统计初始值个数,并相应地设置数组大小。
- 可以使用这种语法重新初始化一个数组而无须创建新变量。
smallPrimes = new int [] { 17, 19, 23, 29, 31, 37 };
- 创建一个数字数组时,所有元素都初始化为 0,boolean 数组的元素会初始化为 false,对象数组的元素则初始化为一个特殊值 null, 表示这些元素未存放任何对象。
- 要想获得数组中的元素个数,可以使用 array.length。
2.10.2 foreach 循环
- Java 有 一种功能很强的循环结构,可以用来依次处理数组(或者其他元素集合)中的每个元素,而不必考虑指定下标值。
- 这种增强的 for 循环的语句格式为:
for (variable : collection) statement;
- 它定义一个变量用于暂存集合中的每一个元素,并执行相应的语句。
- collection 这一集合表达式必须是一个数组或者是一个实现了 Iterable 接口的类对象(例如 Arraylist) 。
- for each 循环语句的循环变量将会遍历数组中的每个元素,而不是下标值。
- 这种增强的 for 循环的语句格式为:
2.10.3 数组拷贝和数组排序
- 在 Java 中,允许将一个数组变量拷贝到另 一个数组变量,这时,两个变量将引用同一个数组。
- 如果希望将一个数组的所有值拷贝到一个新的数组中去,就要使用 Arrays 类的 copyOf 方法:
int[] copiedluckyNumbers = Arrays.copyOf(luckyNumbers, luckyNumbers.length);
- 第 2 个参数是新数组的长度,这个方法通常用来增加数组的大小。
- 如果希望将一个数组的所有值拷贝到一个新的数组中去,就要使用 Arrays 类的 copyOf 方法:
- 要想对数值型数组进行排序, 可以使用 Arrays 类中的 sort 方法,这个方法使用了优化的快速排序 ( QuickSort ) 算法。
- static String toString(xxx [] a}
- 返回包含 a 中元素的一个字符串,这些元素用中括号包围,并用逗号分隔。
- 在这个方法以及后面的方法中,数组元素类型可以是 int、long、short、char、byte、boolean、float 或 double。
- static xxx[ ] copyOf(xxx[ ] a, int end}/static xxx[ ] copyOfRange(xxx[ ] a, int start, int end}
- 返回与 a 类型相同的一个数组, 其长度为 length 或者 end-start,数组元素为 a 的值。
- 如果 end 大于 a.length,结果会填充 0 或 false 值。
- static void sort(xxx [] a}
- 使用优化的快速排序算法对数组进行排序。
- static int binarySearch(xxx [ ] a, xxx v}/static int binarySearch (xxx[ ] a, int start , int end , xxx v)
- 使用二分查找算法在有序数组 a 中查找值 v。
- 如果找到 v, 则返回相应的下标;
- 否则,返回一个负数值 r 是 v 应插入的位置(为保持 a 有序)。
- static void fill (xxx [ ] a, xxx v)
- 将数组的所有数据元素设置为 v。
- static boolean equals(xxx[ ] a, xxx[ ] b)
- 如果两个数组大小相同,并且下标相同的元素都对应相等,返回 true。
- Java 实际上没有多维数组,只有一维数组,多维数组被解释为“数组的数组”。