ArrayList操作详解与实战应用
以下是各程序清单的执行结果及核心要点解析:
Listing 1: ArrayListDemo
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
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
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的索引操作(get、set),但效率较低。
Listing 4: HashSetDemo
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
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
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
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+解析:
- 演示了
Iterator和ListIterator的用法。Iterator用于单向遍历集合。 ListIterator是Iterator的增强版,支持双向遍历(hasPrevious(),previous())和在遍历过程中修改元素(set())。
Listing 8: ForEachDemo
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
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
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
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
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 (自定义比较器)
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表达式比较器)
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 (按姓氏排序)
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)
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
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
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
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)
// 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
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)
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)
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)
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.解析:
Properties是Hashtable的子类,用于管理属性列表(键值均为字符串)。getProperty(key, defaultValue)方法在键不存在时返回默认值。
Listing 26: PropDemoDef (带默认值的 Properties)
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 文件存储)
/* 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")将属性列表存储到文件输出流,并附带注释。- 程序实现了数据的持久化存储和读取。
参考来源
- 【Java】集合框架,集合类+工具类
- 【Java 集合框架】最全的 Java 集合框架入门手册
- 深入解析Java集合框架:分类、实现原理与代码示例
- Java笔记——Java集合框架_java 集合框架
- Java集合框架
