This website requires JavaScript.

Core Java 读书笔记一:Java 的基本程序设计结构

数据类型

Unicode 类型

在 Unicode 标准中,码点(code point)使用16进制表示,并加上前缀 U+,比如 U+0041 是子母A的码点。 Unicode 的码点被分为17层面(code plane)。第一层为基本多语种层(basic multilingual plane),从 U+0000 到 U+FFFF。剩余的16个层面为 U+10000 到 U+10FFFF 为补充字符(supplementary characters)。

UTF-16 编码采用不同长度的编码表示所有 Unicode 码点。在基本多语种层采用16位记录,称之为代码单元(code unit)。而辅助字符采用一对连续的代码单元进行编码。 这样构成的编码值落人基本的多语言级别中空闲的 2048 字节内, 通常被称为替代区域(surrogate area)(比如 U+D800 ~ U+DBFF 用于第一个代码单元,U+DC00 ~ U+DFFF 用于第二个代码单元)。 这样设计十分巧妙, 我们可以从中迅速地知道一个代码单元是一个字符的编码,还是一个辅助字符的第一或第二部分。

在 Java 中,char 类型描述了 UTF-16 编码中的一个代码单元。我们强烈建议不要在程序中使用 char 类型, 除非确实需要处理 UTF-16 代码单元。最好将字符串作为抽象数据类型处理。

枚举类型

有时候,变量的取值只在一个有限的集合内。例如: 销售的服装或比萨饼只有小、中、 大和超大这四种尺寸。当然,可以将这些尺寸分别编码为 1、2、3、4 或 S、 M、 L、X。但 这样存在着一定的隐患。在变量中很可能保存的是一个错误的值(如 0 或 m )。 针对这种情况 可以自定义枚举类型 枚举类型包括有限个命名的值例如:

enum Size { SMALL, MEDIUM, LARGE, EXTRA_LARCE };

实际上, 这个声明定义的类型是一个类, 它刚好有 4 个实例, 在此尽量不要构造新对象。

现在,可以声明这种类型的变量:

Size s = Size.MEDIUM;

Size 类型的变量只能存储这个类型声明中给定的某个枚举值,或者 null 值, null 表示这个变量没有设置任何值。

如果需要的话, 可以在枚举类型中添加一些构造器、 方法和域。 当然, 构造器只是在构造枚举常量的时候被调用。 下面是一个示例:

public enum Size
{
  SMALLfS") , MEDIUMC'M") , LARGEfL") , EXTRA_LARGE("XL") ;
  private String abbreviation;
  
  private Size(String abbreviation) { this, abbreviation = abbreviation; }
  public String getAbbreviation() { return abbreviation; }
}

字符串

概念上讲,Java 字符串就是 Unicode 字符序列。

Java 字符串由 char 值序列组成。 char 数据类型是一个采用 UTF-16 编码表示 Unicode 码点的代码单元。大多数的常用 Unicode 字符使用一个代码单元就可以表示,而辅助字符需要一对代码单元表示。 length 方法将返回采用 UTF-16 编码表示的给定字符串所需要的代码单元数量。 例如:

String greeting = "Hello";
int n = greeting.length(); // is 5

构建字符串

有些时候, 需要由较短的字符串构建字符串, 例如, 按键或来自文件中的单词。 采用字 符串连接的方式达到此目的效率比较低。 每次连接字符串,都会构建一个新的 String 对象,既耗时,又浪费空间。使用 StringBuilder 类就可以避免这个问题的发生。

如果需要用许多小段的字符串构建一个字符串, 那么应该按照下列步骤进行。 首先,构建一个空的字符串构建器:

StringBuilder builder = new StringBuilderO;

当每次需要添加一部分内容时, 就调用 append 方法。

builder.append(ch); // appends a single character
bui1der.append(str); // appends a string

在需要构建字符串时就凋用 toString 方法, 将可以得到一个 String 对象, 其中包含了构建器 中的字符序列。

String completedString = builder.toStringO;

在 JDK5.0 中引入 StringBuilder 类。 这个类的前身是 StringBuffer, 其效率稍有些低, 但允许采用多线程的方式执行添加或删除字符的操作。如果所有字符串在一个单线程中编辑 (通常都是这样) ,则应该用 StringBuilder 替代它。 这两个类的 API是相同的。

大数值

如果基本的整数和浮点数精度不能够满足需求, 那么可以使用 jaVa.math 包中的两个 很有用的类: Biglnteger 和 BigDecimaL 这两个类可以处理包含任意长度数字序列的数值。 Biglnteger 类实现了任意精度的整数运算, BigDecimal 实现了任意精度的浮点数运算。 使用静态的 valueOf 方法可以将普通的数值转换为大数值:

Biglnteger a = Biglnteger.valueOf(100);

遗憾的是, 不能使用人们熟悉的算术运算符(如: + 和 * ) 处理大数值。 而需要使用大数 值类中的 add 和 multiply 方法。

Biglnteger c = a.add(b); // c = a + b
Biglnteger d = c.nultipiy(b.add(Biglnteger.valueOf(2))); // d = c * (b + 2)

数组

在声明数组变量时, 需要指出数组类型 (数据元素类型紧跟 [] ) 和数组变量的名字。 下面声明了整型数组 a:

int[] a;
或
int a[]

不过,这条语句只声明了变量 a,并没有将 a 初始化为一个真正的数组。 应该使用 new 运算 符创建数组。

int[] a = new int[100];

创建一个数字数组时, 所有元素都初始化为 0。boolean 数组的元素会初始化为 false 对象数组的元素则初始化为一个特殊值null, 这表示这些元素(还)未存放任何对象。

String[] names = new String[10];

for each 循环

for (int i = 0; i < a.length; i++) System,out.println(a[i]);

直接打印数组中的所有值

System.out.println(Arrays.toString(a)) ;

数组初始化以及匿名数组

初始化,不需要用 new

int[] anonymous = { 17, 19, 23, 29, 31, 37 };
smallPrimes = anonymous;
//匿名数组,使用这种语法形式可以在不创建新变量的情况下重新初始化一个数组。
new intD { 17, 19, 23, 29, 31, 37 }
small Primes = new int[] { 17, 19, 23, 29, 31, 37 };

数组拷贝

在 Java 中, 允许将一个数组变量拷贝给 另一个数组变量。这时, 两个变量将引用同 一个数组:

intQ luckyNumbers = smallPrimes;
1uckyNumbers[S] = 12; // now smallPrimes[5] is also 12

如果希望将 一个数组的所有值拷贝到一个新的数组中去, 就要使用 Arrays 类的 copyOf 方法:

int[] copiedLuckyNumbers = Arrays.copyOf(luckyNumbers, luckyNumbers.length);
// 第 2 个参数是新数组的长度。 这个方法通常用来增加数组的大小。如果数组元素是数值型, 那么多余的元素将被赋值为 0 ; 如果数组元素是布尔型, 则将赋值
为 false。 相反, 如果长度小于原始数组的长度, 则只拷贝最前面的数据元素。
luckyNumbers = Arrays.copyOf(luckyNumbers, 2 * luckyNumbers.length);

多维数组

声明一个二维数组

double[][] balances;

与一维数组一样, 在调用 new 对多维数组进行初始化之前不能使用它。 在这里可以这样 初始化:

balances = new double[NYEARS][NRATES]:

另外, 如果知道数组元素, 就可以不调用 new, 而直接使用简化的书写形式对多维数组 进行初始化。 例如:

int[][] magicSquare = {
{16, 3, 2, 13},
{5, 10, 11, 8},
{9, 6, 7, 12},
{4, 15, 14, 1}
};
0条评论
avatar