OCA/OCP Java Note (6): Core Java APIs (1)

1. Creating and Manipulating Strings

1.1. Concatenation

  使用“+”运算符进行字符串拼接时,需要注意:

  1. 如果两个操作数都是数值,则+表示数值加;
  2. 如果有一个操作数时String,则+表示拼接;
  3. 表达式按照从左向右的顺序求值。

eg.

System.out.println(1 + 2);          // 3
System.out.println("a" + "b");      // ab
System.out.println("a" + "b" + 3);  // ab3
System.out.println(1 + 2 + "c");    // 3c

1.2. Immutability

  String是immutable的。

eg.

String s1 = "1";
String s2 = s1.concat("2");
s2.concat("3");
System.out.println(s2);  //12

1.3. The String Pool

  JVM使用字符串池保存字符串以便重复利用,其中包括程序中出现的字面值,如“name”。其他如myObject.toString() 虽然也是String,但不是字面值,不会保存在字符串池中。如以下两种用法:

String name = "Fluffy";              //使用字符串池
String name = new String("Fluffy");  //不使用字符串池,创建新的字符串

2. Using the StringBuilder Class

  StringBuilder是mutable的。

eg.

4: StringBuilder sb = new StringBuilder("start");
5: sb.append("+middle");                    // sb = "start+middle"
6: StringBuilder same = sb.append("+end");  // "start+middle+end"
4: StringBuilder a = new StringBuilder("abc");
5: StringBuilder b = a.append("de");
6: b = b.append("f").append("g");
7: System.out.println("a=" + a);            //abcdefg
8: System.out.println("b=" + b);            //abcdefg

new StringBuilder() 只出现了一次,只有一个StringBuilder实例被创建。

2.1. StringBuilder vs. StringBuffer

  StringBuffer功能与StringBuilder类似,但由于StringBuffer是线程安全的,其速度低于StringBuilder。

3. Understanding Equality

eg.

String x = "Hello World";
String y = "Hello World";
String z = " Hello World".trim();
System.out.println(x == y);  // true
System.out.println(x == z);  // false

字符串字面值存储于字符串池,x和y引用是相等的,String.trim()生成了新的字符串对象,x和z不相等。

4. Understanding Java Arrays

  可以使用以下几种方式声明数组:

int[] numAnimals;
int [] numAnimals2;
int numAnimals3[];
int numAnimals4 [];

中括号前是否有空格没有区别,中括号位置有区别:
int[] ids, types; // ids和types都是数组
int ids[], types; // 只有ids是数组

4.1. Creating an Array with Reference Variables

  数组的equals()方法比较的是引用,而不是数组内容。

eg.

public class ArrayType {
    public static void main(String args[]) {
        String [] bugs = { "cricket", "beetle", "ladybug" };
        String [] alias = bugs;
        System.out.println(bugs.equals(alias));  // true
        System.out.println(bugs.toString());     // [Ljava.lang.String;@160bc7c0
} }

  从Java 5开始,Java提供了一个打印数组内容的方法,在上面的例子中,使用:
java.util.Arrays.toString(bugs)

将输出:
[cricket, beetle, lady-bug]

eg.
3: String[] strings = { "stringValue" };
4: Object[] objects = strings;
5: String[] againStrings = (String[]) objects;
6: againStrings[0] = new StringBuilder();  // DOES NOT COMPILE
7: objects[0] = new StringBuilder();       // careful!

注意第7行,StringBuilder对象可以放置于Object数组中,但在该段代码中,并不存在实际的Object数组,objects仅仅是指向了一个String型数组againStrings,该行运行时将抛出ArrayStoreException。

4.2. Using an Array

eg.

String[] birds = new String[6];    // 6个元素全是null
System.out.println(birds.length);  // 6

4.3. Sorting

  Java提供了Arrays.sort()对数组进行排序(升序),使用前需要import,以下两种形式均可:

import java.util.*        // import whole package including Arrays
import java.util.Arrays;  // import just Arrays

eg.
String[] strings = { "10", "9", "100" };
Arrays.sort(strings);
for (String string : strings)
    System.out.print(string + " ");  // 10 100 9

对String数组的排序是按照字母顺序进行的,数字排在字母前面,小写字母排在大写前面。

4.4. Searching

  Java提供了Arrays.binarySearch()对已排序(升序)的数组进行二分查找,规则为:

Scenario Result
被查找数组已排序,包含查找的目标元素 目标元素的索引序号
被查找数组已排序,不包含目标元素 目标元素应被插入的位置p的相反数再减1(-p-1)
被查找数组未排序 不可预测的结果

eg.

3: int[] numbers = {2,4,6,8};
4: System.out.println(Arrays.binarySearch(numbers, 2));  // 0
5: System.out.println(Arrays.binarySearch(numbers, 4));  // 1
6: System.out.println(Arrays.binarySearch(numbers, 1));  // -1
7: System.out.println(Arrays.binarySearch(numbers, 3));  // -2
8: System.out.println(Arrays.binarySearch(numbers, 9));  // -5

4.5. Varargs

  main()的参数是一个String数组,可以使用以下三种方式:

public static void main(String[] args)
public static void main(String args[])
public static void main(String... args)  // varargs

第三种String… args 使用了可变参数,可以像普通数组那样使用,如args.length和args[0] 等都是合法的。

4.6. Multidimensional Arrays

  多维数组中,每一维度可以具有不同的长度。

eg. 遍历多维数组:

int[][] differentSize = {{1, 4}, {3}, {9,8,7}};
for (int[] inner : twoD) {
    for (int num : inner)
        System.out.print(num + " ");
    System.out.println();
}