ArrayList操作详解与实战应用

以下是各程序清单的执行结果及核心要点解析:

Listing 1: ArrayListDemo

java 复制代码
import java.util.*;
class ArrayListDemo {
  public static void main(String args[]) {
    ArrayList<String> al = new ArrayList<String>();
    System.out.println("Initial size of al: " + al.size());
    al.add("C");
    al.add("A");
    al.add("E");
    al.add("B");
    al.add("D");
    al.add("F");
    al.add(1, "A2");
    System.out.println("Size of al after additions: " + al.size());
    System.out.println("Contents of al: " + al);
    al.remove("F");
    al.remove(2);
    System.out.println("Size of al after deletions: " + al.size());
    System.out.println("Contents of al: " + al);
  }
}

执行结果:

复制代码
Initial size of al: 0
Size of al after additions: 7
Contents of al: [C, A2, A, E, B, D, F]
Size of al after deletions: 5
Contents of al: [C, A2, E, B, D]

解析:

  • 演示了 ArrayList 的基本操作:创建、获取大小、添加元素(包括在指定索引处插入)、删除元素(按对象和按索引)以及打印内容。
  • al.add(1, "A2") 在索引1处插入元素,后续元素后移。
  • al.remove("F") 删除第一个匹配的 "F" 元素。
  • al.remove(2) 删除索引为2的元素(此时是 "A")。

Listing 2: ArrayListToArray

java 复制代码
import java.util.*;
class ArrayListToArray {
  public static void main(String args[]) {
    ArrayList<Integer> al = new ArrayList<Integer>();
    al.add(1);
    al.add(2);
    al.add(3);
    al.add(4);
    System.out.println("Contents of al: " + al);
    Integer ia[] = new Integer[al.size()];
    ia = al.toArray(ia);
    int sum = 0;
    for(int i : ia) sum += i;
    System.out.println("Sum is: " + sum);
  }
}

执行结果:

复制代码
Contents of al: [1, 2, 3, 4]
Sum is: 10

解析:

  • 演示了如何将 ArrayList 转换为数组。al.toArray(ia) 方法将列表元素复制到提供的数组 ia 中并返回该数组。

Listing 3: LinkedListDemo

java 复制代码
import java.util.*;
class LinkedListDemo {
  public static void main(String args[]) {
    LinkedList<String> ll = new LinkedList<String>();
    ll.add("F");
    ll.add("B");
    ll.add("D");
    ll.add("E");
    ll.add("C");
    ll.addLast("Z");
    ll.addFirst("A");
    ll.add(1, "A2");
    System.out.println("Original contents of ll: " + ll);
    ll.remove("F");
    ll.remove(2);
    System.out.println("Contents of ll after deletion: " + ll);
    ll.removeFirst();
    ll.removeLast();
    System.out.println("ll after deleting first and last: " + ll);
    String val = ll.get(2);
    ll.set(2, val + " Changed");
    System.out.println("ll after change: " + ll);
  }
}

执行结果:

复制代码
Original contents of ll: [A, A2, F, B, D, E, C, Z]
Contents of ll after deletion: [A, A2, D, E, C, Z]
ll after deleting first and last: [A2, D, E, C]
ll after change: [A2, D, E Changed, C]

解析:

  • 演示了 LinkedList 作为双向链表的特有操作:addFirst()addLast()removeFirst()removeLast()
  • 也支持类似 ArrayList 的索引操作(getset),但效率较低。

Listing 4: HashSetDemo

java 复制代码
import java.util.*;
class HashSetDemo {
  public static void main(String args[]) {
    HashSet<String> hs = new HashSet<String>();
    hs.add("Beta");
    hs.add("Alpha");
    hs.add("Eta");
    hs.add("Gamma");
    hs.add("Epsilon");
    hs.add("Omega");
    System.out.println(hs);
  }
}

执行结果(示例,顺序不保证):

复制代码
[Gamma, Alpha, Epsilon, Omega, Beta, Eta]

解析:

  • HashSet 是基于哈希表实现的集合,不保证元素的顺序(既不是插入顺序,也不是排序顺序)。
  • 它不允许重复元素。

Listing 5: TreeSetDemo

java 复制代码
import java.util.*;
class TreeSetDemo {
  public static void main(String args[]) {
    TreeSet<String> ts = new TreeSet<String>();
    ts.add("C");
    ts.add("A");
    ts.add("B");
    ts.add("E");
    ts.add("F");
    ts.add("D");
    System.out.println(ts);
  }
}

执行结果:

复制代码
[A, B, C, D, E, F]

解析:

  • TreeSet 是基于红黑树(一种自平衡二叉查找树)实现的集合,元素会按照自然顺序(或指定的 Comparator)自动排序。

Listing 6: ArrayDequeDemo

java 复制代码
import java.util.*;
class ArrayDequeDemo {
  public static void main(String args[]) {
    ArrayDeque<String> adq = new ArrayDeque<String>();
    adq.push("A");
    adq.push("B");
    adq.push("D");
    adq.push("E");
    adq.push("F");
    System.out.print("Popping the stack: ");
    while(adq.peek() != null)
      System.out.print(adq.pop() + " ");
    System.out.println();
  }
}

执行结果:

复制代码
Popping the stack: F E D B A

解析:

  • ArrayDeque 是一个基于数组的双端队列。这里使用 push()pop() 方法将其作为栈(后进先出,LIFO)使用。
  • push(E e) 等效于 addFirst(e)pop() 等效于 removeFirst()

Listing 7: IteratorDemo

java 复制代码
import java.util.*;
class IteratorDemo {
  public static void main(String args[]) {
    ArrayList<String> al = new ArrayList<String>();
    al.add("C"); al.add("A"); al.add("E"); al.add("B"); al.add("D"); al.add("F");
    System.out.print("Original contents of al: ");
    Iterator<String> itr = al.iterator();
    while(itr.hasNext()) {
      String element = itr.next();
      System.out.print(element + " ");
    }
    System.out.println();
    ListIterator<String> litr = al.listIterator();
    while(litr.hasNext()) {
      String element = litr.next();
      litr.set(element + "+");
    }
    System.out.print("Modified contents of al: ");
    itr = al.iterator();
    while(itr.hasNext()) {
      String element = itr.next();
      System.out.print(element + " ");
    }
    System.out.println();
    System.out.print("Modified list backwards: ");
    while(litr.hasPrevious()) {
      String element = litr.previous();
      System.out.print(element + " ");
    }
    System.out.println();
  }
}

执行结果:

复制代码
Original contents of al: C A E B D F
Modified contents of al: C+ A+ E+ B+ D+ F+
Modified list backwards: F+ D+ B+ E+ A+ C+

解析:

  • 演示了 IteratorListIterator 的用法。Iterator 用于单向遍历集合。
  • ListIteratorIterator 的增强版,支持双向遍历(hasPrevious(), previous())和在遍历过程中修改元素(set())。

Listing 8: ForEachDemo

java 复制代码
import java.util.*;
class ForEachDemo {
  public static void main(String args[]) {
    ArrayList<Integer> vals = new ArrayList<Integer>();
    vals.add(1); vals.add(2); vals.add(3); vals.add(4); vals.add(5);
    System.out.print("Original contents of vals: ");
    for(int v : vals)
      System.out.print(v + " ");
    System.out.println();
    int sum = 0;
    for(int v : vals)
      sum += v;
    System.out.println("Sum of values: " + sum);
  }
}

执行结果:

复制代码
Original contents of vals: 1 2 3 4 5
Sum of values: 15

解析:

  • 演示了增强型 for 循环(for-each 循环)遍历集合。语法简洁,无需显式使用迭代器。

Listing 9: SpliteratorDemo

java 复制代码
import java.util.*;
class SpliteratorDemo {
  public static void main(String args[]) {
    ArrayList<Double> vals = new ArrayList<>();
    vals.add(1.0); vals.add(2.0); vals.add(3.0); vals.add(4.0); vals.add(5.0);
    System.out.print("Contents of vals:
");
    Spliterator<Double> spltitr = vals.spliterator();
    while(spltitr.tryAdvance((n) -> System.out.println(n)));
    System.out.println();
    spltitr = vals.spliterator();
    ArrayList<Double> sqrs = new ArrayList<>();
    while(spltitr.tryAdvance((n) -> sqrs.add(Math.sqrt(n))));
    System.out.print("Contents of sqrs:
");
    spltitr = sqrs.spliterator();
    spltitr.forEachRemaining((n) -> System.out.println(n));
    System.out.println();
  }
}

执行结果:

复制代码
Contents of vals:
1.0
2.0
3.0
4.0
5.0Contents of sqrs:
1.0
1.4142135623730951
1.7320508075688772
2.02.23606797749979

解析:

  • 演示了 Java 8 引入的 Spliterator(可分割迭代器),用于遍历和分割源元素,特别适合并行处理。
  • tryAdvance() 逐个消费元素,forEachRemaining() 消费剩余所有元素。

Listing 10: MailList

java 复制代码
import java.util.*;
class Address {
  private String name; private String street; private String city; private String state; private String code;
  Address(String n, String s, String c, String st, String cd) { name = n; street = s; city = c; state = st; code = cd; }
  public String toString() { return name + "
" + street + "
" + city + " " + state + " " + code; }
}
class MailList {
  public static void main(String args[]) {
    LinkedList<Address> ml = new LinkedList<Address>();
    ml.add(new Address("J.W. West", "11 Oak Ave", "Urbana", "IL", "61801"));
    ml.add(new Address("Ralph Baker", "1142 Maple Lane", "Mahome", "IL", "61853"));
    ml.add(new Address("Tom Carlton", "867 Elm St", "Champaign", "IL", "61820"));
    for(Address element : ml)
      System.out.println(element + "
");
    System.out.println();
  }
}

执行结果:

复制代码
J.W. West
11 Oak Ave
Urbana IL 61801

Ralph Baker
1142 Maple Lane
Mahome IL 61853

Tom Carlton
867 Elm St
Champaign IL 61820

解析:

  • 展示了在集合(LinkedList)中存储自定义对象(Address)。
  • 通过重写 toString() 方法,可以方便地打印对象内容。

Listing 11: HashMapDemo

java 复制代码
import java.util.*;
class HashMapDemo {
  public static void main(String args[]) {
    HashMap<String, Double> hm = new HashMap<String, Double>();
    hm.put("John Doe", 3434.34);
    hm.put("Tom Smith", 123.22);
    hm.put("Jane Baker", 1378.00);
    hm.put("Tod Hall", 99.22);
    hm.put("Ralph Smith", -19.08);
    Set<Map.Entry<String, Double>> set = hm.entrySet();
    for(Map.Entry<String, Double> me : set) {
      System.out.print(me.getKey() + ": ");
      System.out.println(me.getValue());
    }
    System.out.println();
    double balance = hm.get("John Doe");
    hm.put("John Doe", balance + 1000);
    System.out.println("John Doe's new balance: " + hm.get("John Doe"));
  }
}

执行结果(示例,顺序不保证):

复制代码
Ralph Smith: -19.08
Tom Smith: 123.22
John Doe: 3434.34
Tod Hall: 99.22
Jane Baker: 1378.0

John Doe's new balance: 4434.34

解析:

  • 演示了 HashMap 的基本操作:put() 添加键值对,get() 根据键获取值,entrySet() 获取包含所有映射的集合视图用于遍历。
  • HashMap 不保证映射的顺序。

Listing 12: TreeMapDemo

java 复制代码
import java.util.*;
class TreeMapDemo {
  public static void main(String args[]) {
    TreeMap<String, Double> tm = new TreeMap<String, Double>();
    tm.put("John Doe", 3434.34);
    tm.put("Tom Smith", 123.22);
    tm.put("Jane Baker", 1378.00);
    tm.put("Tod Hall", 99.22);
    tm.put("Ralph Smith", -19.08);
    Set<Map.Entry<String, Double>> set = tm.entrySet();
    for(Map.Entry<String, Double> me : set) {
      System.out.print(me.getKey() + ": ");
      System.out.println(me.getValue());
    }
    System.out.println();
    double balance = tm.get("John Doe");
    tm.put("John Doe", balance + 1000);
    System.out.println("John Doe's new balance: " + tm.get("John Doe"));
  }
}

执行结果:

复制代码
Jane Baker: 1378.0
John Doe: 3434.34
Ralph Smith: -19.08
Tod Hall: 99.22
Tom Smith: 123.22John Doe's new balance: 4434.34

解析:

  • TreeMap 是基于红黑树实现的 Map,会根据键的自然顺序(或指定的比较器)对键进行排序。
  • 输出顺序是按键(姓名)的字典序排列的。

Listing 13: CompDemo (自定义比较器)

java 复制代码
import java.util.*;
class MyComp implements Comparator<String> {
  public int compare(String aStr, String bStr) {
    return bStr.compareTo(aStr); // 反向比较
  }
}
class CompDemo {
  public static void main(String args[]) {
    TreeSet<String> ts = new TreeSet<String>(new MyComp());
    ts.add("C"); ts.add("A"); ts.add("B"); ts.add("E"); ts.add("F"); ts.add("D");
    for(String element : ts)
      System.out.print(element + " ");
    System.out.println();
  }
}

执行结果:

复制代码
F E D C B A

解析:

  • 通过实现 Comparator 接口并重写 compare 方法,可以自定义 TreeSet 的排序规则。此处实现了降序排序。

Listing 14: CompDemo2 (Lambda表达式比较器)

java 复制代码
import java.util.*;
class CompDemo2 {
  public static void main(String args[]) {
    TreeSet<String> ts = new TreeSet<String>((aStr, bStr) -> bStr.compareTo(aStr));
    ts.add("C"); ts.add("A"); ts.add("B"); ts.add("E"); ts.add("F"); ts.add("D");
    for(String element : ts)
      System.out.print(element + " ");
    System.out.println();
  }
}

执行结果:

复制代码
F E D C B A

解析:

  • 使用 Lambda 表达式简化了自定义比较器的创建,功能与 Listing 13 相同,代码更简洁。

Listing 15: TreeMapDemo2 (按姓氏排序)

java 复制代码
import java.util.*;
class TComp implements Comparator<String> {
  public int compare(String aStr, String bStr) {
    int i, j, k;
    i = aStr.lastIndexOf(' ');
    j = bStr.lastIndexOf(' ');
    k = aStr.substring(i).compareToIgnoreCase(bStr.substring(j));
    if(k==0)
      return aStr.compareToIgnoreCase(bStr);
    else
      return k;
  }
}
class TreeMapDemo2 {
  public static void main(String args[]) {
    TreeMap<String, Double> tm = new TreeMap<String, Double>(new TComp());
    tm.put("John Doe", 3434.34);
    tm.put("Tom Smith", 123.22);
    tm.put("Jane Baker", 1378.00);
    tm.put("Tod Hall", 99.22);
    tm.put("Ralph Smith", -19.08);
    Set<Map.Entry<String, Double>> set = tm.entrySet();
    for(Map.Entry<String, Double> me : set) {
      System.out.print(me.getKey() + ": ");
      System.out.println(me.getValue());
    }
    System.out.println();
    double balance = tm.get("John Doe");
    tm.put("John Doe", balance + 1000);
    System.out.println("John Doe's new balance: " + tm.get("John Doe"));
  }
}

执行结果:

复制代码
Jane Baker: 1378.0
John Doe: 3434.34
Tod Hall: 99.22
Ralph Smith: -19.08
Tom Smith: 123.22

John Doe's new balance: 4434.34

解析:

  • 自定义比较器 TComp 首先比较键字符串的姓氏(最后一个空格后的部分),如果姓氏相同,则比较全名。
  • 因此,"Ralph Smith" 排在 "Tom Smith" 之前。

Listing 16: TreeMapDemo2A (使用 thenComparing)

java 复制代码
import java.util.*;
class CompLastNames implements Comparator<String> {
  public int compare(String aStr, String bStr) {
    int i = aStr.lastIndexOf(' ');
    int j = bStr.lastIndexOf(' ');
    return aStr.substring(i).compareToIgnoreCase(bStr.substring(j));
  }
}
class CompThenByFirstName implements Comparator<String> {
  public int compare(String aStr, String bStr) {
    return aStr.compareToIgnoreCase(bStr);
  }
}
class TreeMapDemo2A {
  public static void main(String args[]) {
    CompLastNames compLN = new CompLastNames();
    Comparator<String> compLastThenFirst = compLN.thenComparing(new CompThenByFirstName());
    TreeMap<String, Double> tm = new TreeMap<String, Double>(compLastThenFirst);
    tm.put("John Doe", 3434.34);
    tm.put("Tom Smith", 123.22);
    tm.put("Jane Baker", 1378.00);
    tm.put("Tod Hall", 99.22);
    tm.put("Ralph Smith", -19.08);
    Set<Map.Entry<String, Double>> set = tm.entrySet();
    for(Map.Entry<String, Double> me : set) {
      System.out.print(me.getKey() + ": ");
      System.out.println(me.getValue());
    }
    System.out.println();
    double balance = tm.get("John Doe");
    tm.put("John Doe", balance + 1000);
    System.out.println("John Doe's new balance: " + tm.get("John Doe"));
  }
}

执行结果:

复制代码
Jane Baker: 1378.0
John Doe: 3434.34
Tod Hall: 99.22
Ralph Smith: -19.08
Tom Smith: 123.22

John Doe's new balance: 4434.34

解析:

  • 使用 Comparator.thenComparing() 方法组合多个比较器。先按姓氏比较(CompLastNames),如果姓氏相同,再按全名比较(CompThenByFirstName)。
  • 结果与 Listing 15 相同,但实现方式更模块化。

Listing 17: AlgorithmsDemo

java 复制代码
import java.util.*;
class AlgorithmsDemo {
  public static void main(String args[]) {
    LinkedList<Integer> ll = new LinkedList<Integer>();
    ll.add(-8); ll.add(20); ll.add(-20); ll.add(8);
    Comparator<Integer> r = Collections.reverseOrder();
    Collections.sort(ll, r);
    System.out.print("List sorted in reverse: ");
    for(int i : ll) System.out.print(i+ " ");
    System.out.println();
    Collections.shuffle(ll);
    System.out.print("List shuffled: ");
    for(int i : ll) System.out.print(i + " ");
    System.out.println();
    System.out.println("Minimum: " + Collections.min(ll));
    System.out.println("Maximum: " + Collections.max(ll));
  }
}

执行结果(示例,shuffle 结果随机):

复制代码
List sorted in reverse: 20 88 -20
List shuffled: 8 -20 20 -8
Minimum: -20
Maximum: 20

解析:

  • 演示了 Collections 工具类的常用算法:sort() 排序(可传入反向比较器)、shuffle() 随机打乱、min() 求最小值、max() 求最大值。

Listing 18: ArraysDemo

java 复制代码
import java.util.*;
class ArraysDemo {
  static void display(int array[]) {
    for(int i: array) System.out.print(i + " ");
    System.out.println();
  }
  public static void main(String args[]) {
    int array[] = new int[10];
    for(int i = 0; i < 10; i++) array[i] = -3 * i;
    System.out.print("Original contents: ");
    display(array);
    Arrays.sort(array);
    System.out.print("Sorted: ");
    display(array);
    Arrays.fill(array, 2, 6, -1);
    System.out.print("After fill(): ");
    display(array);
    Arrays.sort(array);
    System.out.print("After sorting again: ");
    display(array);
    System.out.print("The value -9 is at location ");
    int index = Arrays.binarySearch(array, -9);
    System.out.println(index);
  }
}

执行结果:

复制代码
Original contents: 0 -3 -6 -9 -12 -15 -18 -21 -24 -27
Sorted: -27 -24 -21 -18 -15 -12 -9 -63 0
After fill(): -27 -24 -1 -1 -1 -1 -9 -6 -3 0
After sorting again: -27 -24 -9 -6 -3 -1 -1 -1 -1 0The value -9 is at location 2

解析:

  • 演示了 Arrays 工具类的常用方法:sort() 排序、fill() 填充指定范围的元素、binarySearch() 在已排序数组中进行二分查找。

Listing 19: VectorDemo

java 复制代码
import java.util.*;
class VectorDemo {
  public static void main(String args[]) {
    Vector<Integer> v = new Vector<Integer>(3, 2);
    System.out.println("Initial size: " + v.size());
    System.out.println("Initial capacity: " + v.capacity());
    v.addElement(1); v.addElement(2); v.addElement(3); v.addElement(4);
    System.out.println("Capacity after four additions: " + v.capacity());
    v.addElement(5);
    System.out.println("Current capacity: " + v.capacity());
    v.addElement(6); v.addElement(7);
    System.out.println("Current capacity: " + v.capacity());
    v.addElement(9); v.addElement(10);
    System.out.println("Current capacity: " + v.capacity());
    v.addElement(11); v.addElement(12);
    System.out.println("First element: " + v.firstElement());
    System.out.println("Last element: " + v.lastElement());
    if(v.contains(3)) System.out.println("Vector contains 3.");
    Enumeration<Integer> vEnum = v.elements();
    System.out.println("
Elements in vector:");
    while(vEnum.hasMoreElements())
      System.out.print(vEnum.nextElement() + " ");
    System.out.println();
  }
}

执行结果:

复制代码
Initial size: 0
Initial capacity: 3
Capacity after four additions: 5
Current capacity: 5
Current capacity: 7
Current capacity: 9
First element: 1
Last element: 12
Vector contains 3.

Elements in vector:
1 2 3 4 5 6 7 9 10 11 12

解析:

  • Vector 是一个线程安全的、可动态增长的对象数组。构造时指定初始容量(3)和容量增量(2)。
  • 当添加元素超过当前容量时,容量按增量(2)增加。
  • 使用传统的 Enumeration 接口进行遍历。

Listing 20 & 21: Vector 的迭代器和 for-each 遍历

(代码接 Listing 19 的 v

java 复制代码
// Listing 20: 使用迭代器
Iterator<Integer> vItr = v.iterator();
System.out.println("
Elements in vector:");
while(vItr.hasNext())
  System.out.print(vItr.next() + " ");
System.out.println();

// Listing 21: 使用增强 for 循环
System.out.println("
Elements in vector:");
for(int i : v)
  System.out.print(i + " ");
System.out.println();

执行结果(接上):

复制代码
Elements in vector:
1 2 3 4 5 6 7 9 10 11 12

Elements in vector:
1 2 3 4 5 6 7 9 10 11 12

解析:

  • 展示了 Vector 的另外两种遍历方式:Iterator 和增强 for 循环,与 ArrayList 用法一致。

Listing 22: StackDemo

java 复制代码
import java.util.*;
class StackDemo {
  static void showpush(Stack<Integer> st, int a) {
    st.push(a);
    System.out.println("push(" + a + ")");
    System.out.println("stack: " + st);
  }
  static void showpop(Stack<Integer> st) {
    System.out.print("pop -> ");
    Integer a = st.pop();
 System.out.println(a);
    System.out.println("stack: " + st);
  }
  public static void main(String args[]) {
    Stack<Integer> st = new Stack<Integer>();
    System.out.println("stack: " + st);
    showpush(st, 42);
    showpush(st, 66);
    showpush(st, 99);
    showpop(st);
    showpop(st);
    showpop(st);
    try {
      showpop(st);
    } catch (EmptyStackException e) {
      System.out.println("empty stack");
    }
  }
}

执行结果:

复制代码
stack: []
push(42)
stack: [42]
push(66)
stack: [42, 66]
push(99)
stack: [42, 66, 99]
pop -> 99
stack: [42, 66]
pop -> 66
stack: [42]
pop -> 42
stack: []
pop -> empty stack

解析:

  • 演示了 Stack(栈,后进先出 LIFO)的基本操作:push() 入栈、pop() 出栈。
  • 空栈调用 pop() 会抛出 EmptyStackException

Listing 23: HTDemo (Hashtable)

java 复制代码
import java.util.*;
class HTDemo {
  public static void main(String args[]) {
    Hashtable<String, Double> balance = new Hashtable<String, Double>();
    Enumeration<String> names;
    String str;
    double bal;
    balance.put("John Doe", 3434.34);
    balance.put("Tom Smith", 123.22);
    balance.put("Jane Baker", 1378.00);
    balance.put("Tod Hall", 99.22);
    balance.put("Ralph Smith", -19.08);
    names = balance.keys();
    while(names.hasMoreElements()) {
      str = names.nextElement();
      System.out.println(str + ": " + balance.get(str));
    }
    System.out.println();
    bal = balance.get("John Doe");
    balance.put("John Doe", bal+1000);
    System.out.println("John Doe's new balance: " + balance.get("John Doe"));
  }
}

执行结果(示例,顺序不保证):

复制代码
Tod Hall: 99.22
John Doe: 3434.34
Tom Smith: 123.22
Ralph Smith: -19.08
Jane Baker: 1378.0

John Doe's new balance: 4434.34

解析:

  • Hashtable 是一个线程安全的、基于哈希表的 Map 实现。它不允许 null 键或值。
  • 使用传统的 Enumeration 遍历键集(keys())。

Listing 24: HTDemo2 (Hashtable with Iterator)

java 复制代码
import java.util.*;
class HTDemo2 {
  public static void main(String args[]) {
    Hashtable<String, Double> balance = new Hashtable<String, Double>();
    String str;
    double bal;
    balance.put("John Doe", 3434.34);
    balance.put("Tom Smith", 123.22);
    balance.put("Jane Baker", 1378.00);
    balance.put("Tod Hall", 99.22);
    balance.put("Ralph Smith", -19.08);
    Set<String> set = balance.keySet();
    Iterator<String> itr = set.iterator();
    while(itr.hasNext()) {
      str = itr.next();
      System.out.println(str + ": " + balance.get(str));
    }
    System.out.println();
    bal = balance.get("John Doe");
    balance.put("John Doe", bal+1000);
    System.out.println("John Doe's new balance: " + balance.get("John Doe"));
  }
}

执行结果(示例,顺序不保证):

复制代码
Tod Hall: 99.22
John Doe: 3434.34
Tom Smith: 123.22
Ralph Smith: -19.08
Jane Baker: 1378.0

John Doe's new balance: 4434.34

解析:

  • 功能与 Listing 23 相同,但使用 keySet() 获取键的 Set 视图,再通过 Iterator 进行遍历,这是更现代的集合遍历方式。

Listing 25: PropDemo (Properties)

java 复制代码
import java.util.*;
class PropDemo {
  public static void main(String args[]) {
    Properties capitals = new Properties();
    capitals.put("Illinois", "Springfield");
    capitals.put("Missouri", "Jefferson City");
    capitals.put("Washington", "Olympia");
    capitals.put("California", "Sacramento");
    capitals.put("Indiana", "Indianapolis");
    Set<?> states = capitals.keySet();
    for(Object name : states)
      System.out.println("The capital of " + name + " is " + capitals.getProperty((String)name) + ".");
    System.out.println();
    String str = capitals.getProperty("Florida", "Not Found");
    System.out.println("The capital of Florida is " + str + ".");
  }
}

执行结果(示例,顺序不保证):

复制代码
The capital of Missouri is Jefferson City.
The capital of Illinois is Springfield.
The capital of Indiana is Indianapolis.
The capital of California is Sacramento.
The capital of Washington is Olympia.

The capital of Florida is Not Found.

解析:

  • PropertiesHashtable 的子类,用于管理属性列表(键值均为字符串)。getProperty(key, defaultValue) 方法在键不存在时返回默认值。

Listing 26: PropDemoDef (带默认值的 Properties)

java 复制代码
import java.util.*;
class PropDemoDef {
  public static void main(String args[]) {
    Properties defList = new Properties();
    defList.put("Florida", "Tallahassee");
    defList.put("Wisconsin", "Madison");
    Properties capitals = new Properties(defList);
    capitals.put("Illinois", "Springfield");
    capitals.put("Missouri", "Jefferson City");
    capitals.put("Washington", "Olympia");
    capitals.put("California", "Sacramento");
    capitals.put("Indiana", "Indianapolis");
    Set<?> states = capitals.keySet();
    for(Object name : states)
      System.out.println("The capital of " + name + " is " + capitals.getProperty((String)name) + ".");
    System.out.println();
    String str = capitals.getProperty("Florida");
    System.out.println("The capital of Florida is " + str + ".");
  }
}

执行结果(示例,顺序不保证):

复制代码
The capital of Missouri is Jefferson City.
The capital of Illinois is Springfield.
The capital of Indiana is Indianapolis.
The capital of California is Sacramento.
The capital of Washington is Olympia.

The capital of Florida is Tallahassee.

解析:

  • 创建 Properties 时可以指定一个默认属性列表。当在主列表中找不到某个键时,会到默认列表中查找。

Listing 27: Phonebook (Properties 文件存储)

java 复制代码
/* A simple telephone number database that uses a property list. */
import java.io.*;
import java.util.*;
class Phonebook {
  public static void main(String args[]) throws IOException {
    Properties ht = new Properties();
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    String name, number;
    FileInputStream fin = null;
    boolean changed = false;
    try { fin = new FileInputStream("phonebook.dat"); } catch(FileNotFoundException e) { }
    try {
      if(fin != null) { ht.load(fin); fin.close(); }
    } catch(IOException e) { System.out.println("Error reading file."); }
    do {
      System.out.println("Enter new name ('quit' to stop): ");
      name = br.readLine();
      if(name.equals("quit")) continue;
      System.out.println("Enter number: ");
      number = br.readLine();
      ht.put(name, number);
      changed = true;
    } while(!name.equals("quit"));
    if(changed) {
      FileOutputStream fout = new FileOutputStream("phonebook.dat");
      ht.store(fout, "Telephone Book");
      fout.close();
    }
    do {
      System.out.println("Enter name to find ('quit' to quit): ");
      name = br.readLine();
      if(name.equals("quit")) continue;
      number = (String) ht.get(name);
      System.out.println(number);
    } while(!name.equals("quit"));
  }
}

执行结果(交互式程序,示例):

复制代码
Enter new name ('quit' to stop):
Alice
Enter number:
123456
Enter new name ('quit' to stop):
Bob
Enter number:
789012
Enter new name ('quit' to stop):
quit
Enter name to find ('quit' to quit):
Alice
123456
Enter name to find ('quit' to quit):
quit

解析:

  • 这是一个完整的电话簿程序,使用 Properties 存储数据。
  • ht.load(fin) 从文件输入流加载属性列表。
  • ht.store(fout, "Telephone Book") 将属性列表存储到文件输出流,并附带注释。
  • 程序实现了数据的持久化存储和读取。

参考来源

相关推荐
神奇霸王龙1 小时前
MCP v5 Agent Skills 屠夫榜:5 旗舰子代理
网络·人工智能·ai·aigc·agent·mcp·skills
Elastic 中国社区官方博客1 小时前
Elasticsearch:语义搜索快速入门
大数据·人工智能·elasticsearch·搜索引擎·全文检索
东坡肘子1 小时前
热茶还是冰咖啡 -- 肘子的 Swift 周报 #147
人工智能·swiftui·swift
Microvision维视智造1 小时前
行业洞察系列 06 | 汽车制造的视觉革命
人工智能·计算机视觉·汽车·视觉检测·制造·机器视觉
观远数据1 小时前
Excel继续用、自研BI、替换BI:产品VP拆解三条路线的隐性成本与能力边界
大数据·人工智能·excel
JJJennie7773 小时前
当AI开始学会欺骗
网络·人工智能
糖果店的幽灵3 小时前
大模型测评DeepEval快速入门-安全与通用指标详解
人工智能·安全·langgraph·大模型测评·deepeval
江畔柳前堤9 小时前
roLabelImg 详细安装教程
开发语言·人工智能·后端·云原生
阿里云大数据AI技术9 小时前
分链路差异化设计的DSP准实时数仓|钛动科技基于阿里云实时计算 Flink 版 + DLF Paimon + EMR Serverless StarRocks 的实践
人工智能·flink