
4.3 原理学习:熟悉Java类、数组、方法、IO流
4.3.1 常用的Java类
1. Number类和Math类
Java为每一个数据类型提供了对应的封装类,这些封装类(如Integer、Long、Byte、Double、Float、Short)都是抽象类Number的子类。
由编译器支持的包装称为装箱。当内置数据类型被当成对象使用时,编译器会把内置数据类型装箱为包装类。编译器也可以把一个对象拆箱为内置数据类型。Number类属于java.lang包。
Java的Math类包含了用于执行基本数学运算的属性和方法,如指数、对数、平方根和三角函数等。Math类的方法都被定义为静态形式,可以在主函数中直接调用。表4.1列出的是Number类和Math类的常用方法。
表4.1 Number类和Math类的常用方法

2. Character类
Java为char类型提供了包装类,即Character类。Character类用于对单个字符进行操作,Character类在对象中包装一个基本数据类型char的值。
Character类提供了一系列方法来操作字符,可以使用Character类的构造函数来创建一个Character对象,例如:

Java编译器会自动创建一个Character对象。例如,将一个char类型的参数传递给需要一个Character类型参数的方法时,编译器会自动地将char类型参数转换为Character对象。这种行为称为装箱,反之称为拆箱。

前面有反斜杠(\)的字符是转义字符。Java的转义字符如表4.2所示。
表4.2 Java的转义字符

Character类的常用方法如表4.3所示。
表4.3 Character类的常用方法

3. String类
在Java中,字符串属于对象,可以使用Java提供的String类来创建和操作字符串。
(1)创建字符串。创建字符串的方式如下:

在程序编译过程中,当遇到字符串常量时,编译器会使用字符串的值来创建一个String对象。可以使用关键字和构造函数来创建String对象,String类有11种构造函数,提供了不同参数来初始化字符串。
(2)字符串长度。在String类中,获取字符串长度的方法为length()。例如,下面的代码执行后,len变量等于4。

(3)连接字符串。String类提供了连接两个字符串的方法concat(),例如:

返回的是string2连接string1的新字符串。也可以对字符串常量使用concat()方法,例如:

还可以使用“+”操作符来连接字符串,例如:

(4)输出格式化字符串。当需要输出格式化字符串时,可以使用printf()方法和format()方法。String类使用静态方法format(),返回一个String对象而不是PrintStream对象。可以用String类的静态方法format()来创建一个可复用的格式化字符串,而不仅仅是用于一次输出。
例如:

用format()方法可以改写为:

(5)String类的常用方法。String类的常用方法如表4.4所示,更多的方法请参考Java String API文档。
表4.4 String类的常用方法

4.3.2 Java数组
Java用数组来存储固定大小的同类型元素,可以声明一个数组变量(如numbers[200])来代替直接声明200个独立变量。
1. 声明数组变量
先须先声明数组变量,才能在程序中使用数组。例如:

2. 创建数组
Java使用new操作符来创建数组,语法如下:

上面语句有两个功能:
(1)使用DataType[arraySize]创建了一个数组。
(2)把新创建的数组的引用赋值给变量dataArray。
数组变量的声明和创建可以用一条语句完成,如下所示:

另外,还可以使用如下的方式创建数组。

数组中的元素是通过索引来访问的,数组的索引从0开始。例如,下面的语句首先声明了一个数组变量testList,接着创建了一个包含5个int类型元素的数组,并且把它的引用赋值给testList变量。例如:

3. 处理数组
如果数组的元素类型和数组的大小都是确定的,就可以使用for循环来处理数组元素。例如:

4. for-each循环
在不使用下标的情况下遍历数组,可以采用for-each循环来处理数组元素。例如:

5. 二维数组
二维数组的每一个元素都是一个一维数组,如String str[][] = new String[4][5]。数组的动态初始化如下:
(1)直接为每个一维数组分配空间。

DataType可以是基本数据类型和复合数据类型,arrayLength1和arrayLength2必须为正整数,arrayLength1为行数,arrayLength2为列数。例如:

(2)从最高维开始,分别为每个一维数组分配空间。

解析:str[0]=new String[2]和str[1]=new String[3]是为最高维分配的引用空间,也就是能保存数据的最大长度,可为其每个数组元素单独分配空间,如“str[0][0]=new String("Nice");”。
(3)二维数组的引用。二维数组元素的引用方式为arrayName[index1][index2]。例如:

6. Arrays类
java.util.Arrays类可以操作数组,它提供的方法具有以下特点:
(1)赋值:通过fill方法。
(2)排序:通过sort方法,按升序排序。
(3)比较:通过equals方法比较数组中元素是否相等。
(4)查找数组元素:通过binarySearch方法能对排序好的数组进行二分查找法操作。
Arrays类的方法如表4.5所示。
表4.5 Arrays类的方法

4.3.3 Java方法
1. Java方法的命名规则
Java方法的命名规则如下:
(1)方法名的第一个单词应以小写字母作为开头,后面的单词要首字母大写,不使用连接符,如addApple。
(2)可以用下画线来区分逻辑组件,如testPop_emptyStack。
2. Java方法的定义
定义Java方法的格式为:

方法包含一个方法头和一个方法体。下面是一个方法的所有部分:
(1)修饰符:定义了该方法的访问类型。
(2)返回值类型:方法返回值的数据类型,如果没有返回值,则类型为void。
(3)方法名:方法名和参数表共同构成方法签名。
(4)参数类型:当方法被调用时,传递值给参数,方法也可以不包含任何参数。
(5)方法体:方法体包含具体的语句,用于实现该方法的功能。
3. Java方法的调用
当在程序中调用一个方法时,程序的控制权就交给了被调用的方法,方法被调用后会返回一个值时,因此通常可以将方法的调用当成一个值。例如,求一个最小值的代码如下:

如果方法被调用后的返回值是void,则方法的调用一定是一条语句。例如,方法println返回void。下面的调用是个语句:

下面的例子演示了如何定义一个方法,以及如何调用它。

4.3.4 Java IO流
Java的核心库java.io可提供大部分输入、输出操作所需要的类,输入输出(IO)流的类代表了输入源和输出目标,支持多种格式,如基本类型、对象、本地化字符集等。
一个流可以理解为一个数据序列,输入流表示从一个输入源读数据,输出流表示向一个输出目标写数据。
1. IO流
(1)IO流。IO流的类的层次关系如图4.1所示。

图4.1 IO流的类的层次关系
在java.io中,用于对文件内容进行操作的主要是字节流和字符流,它们都可以分为输入操作和输出操作。
• InputStream和OutputStream:主要用来处理字节或二进制对象,是为字节流设计的。
• Reader和Writer:主要用来处理字符或字符串,是为字符流设计的。
(2)字节流转换为字符流。为了便于处理字节流,通常会把字节流转换为字符流。例如,Java的控制台(Console)输入由System.in完成,为了获得一个绑定到控制台的字符流,可以把System.in包装在一个BufferedReader对象中来创建一个字符流。下面是创建BufferedReader对象的方法:

同理,读取文件内容的方法是:

BufferedReader对象可以实现缓冲功能,java.io.BufferedReader类和java.io.BufferedWriter类都拥有8192个字符的缓冲区。当使用BufferedReader对象读取文件内容时,会先从文件中读入字符数据并放入缓冲区,然后使用read()方法从缓冲区读取数据。如果缓冲区数据不足,则再从文件中读取;当使用BufferedWriter对象向文件写入数据时,会先把要写入的数据放到缓冲区中。相关的类分析如下:
• InputStreamReader:将字节流输出为字符流,并且为字节流指定字符集。
• BufferedReader:先从输入流中读取文本,再缓存字符,可以高效地读取字符、数组和行。
InputStream提供的read方法可以从输入流中读取1B的数据,常用的函数原型如下:
① public int read() throws IOException {}。该函数原型从输入流中读取数据的下一个字节。返回值为0~255的int类型字节值。如果已经到达流末尾而没有可用的字节,则返回值-1。在输入数据可用、检测到流末尾或者抛出异常前,read方法将一直阻塞。
返回:下一个数据字节;如果已到达文件末尾,则返回-1。
② public int read (byte[] b) throws IOException{}。从此输入流中将最多b.length个字节的数据读入一个byte类型数组中。在某些输入可用之前,read方法将阻塞。该函数原型覆写了InputStream类中的read方法;其参数为存储读取数据的缓冲区;其返回值为读入缓冲区的字节总数,如果因为已经到达文件末尾而没有更多的数据,则返回-1。

控制台的输出由print和println()方法完成,这些方法都由PrintStream类定义,System.out是PrintStream类对象的一个引用。PrintStream继承自OutputStream类,并且实现了write方法,write方法也可以用来在控制台进行写操作。
2. 与文件相关的类
与文件相关的类如下:
(1)File类:以抽象的方式表示文件名或目录名,该类主要用于文件和目录的创建、文件的查找和删除等。
(2)FileReader类:从InputStreamReader类继承而来,该类按字符读取流中数据。
(3)FileWriter类:从OutputStreamWriter类继承而来,该类按字符向流中写入数据。
File类的部分方法如表4.6所示。
表4.6 File类的部分方法
