Java集合类(Java Collections classes)
2012-11-08 22:31 Justany_WhiteSnow 阅读(672) 评论(0) 编辑 收藏 举报Java集合结构图
Example1:
Problem: Want a simple banking system. Can look up accounts by name or number, deposit or withdraw, print.
问题:设计一个简单的银行系统。可以看到每一个账号里面的名称、编号、存款或取款,并打印之。
方案:
class Account { Account (String name, String number, int init) { this.name = name; this.number = number; this.balance = init; } /** 账号拥有者名字 */ final String name; /** 账号编号 */ final String number; /** 当前余额 */ int balance; /** 按照一定格式打印 */ void print (PrintWriter str) { ... } }
class Bank { SortedMap<String,Account> accounts = new TreeMap<String,Account> (); SortedMap<String,Account> names = new TreeMap<String,Account> (); void openAccount (String name, int initBalance) { Account acc = new Account (name, chooseNumber (), initBalance); accounts.put (acc.number, acc); names.put (name, acc); } void deposit (String number, int amount) { Account acc = accounts.get (number); if (acc == null) ERROR(...); acc.balance += amount; } // 取款也相同 /** 按照账号编号打印 */ void printByAccount (PrintStream str) { for (Account account : accounts.values ()) account.print (str); } /** 按照账号拥有者打印 */ void printByName (PrintStream str) { for (Account account : names.values ()) account.print (str); } }
A Design Question: What would be an appropriate representation for keeping a record of all transactions (deposits and withdrawals) against each account?
一个设计问题:怎样的形式适合存储每个账号的交易(存款或者提款)数据?
Example2
抽象类应用例子。
Problem: Want to create a reversed view of an existing List (same elements in reverse order).
问题:如何创建一个反序列表。
public class ReverseList<Item> extends AbstractList<Item> { private final List<Item> L; public ReverseList (List<Item> L) { this.L = L; } public int size () { return L.size (); } public Item get (int k) { return L.get (L.size ()-k-1); } public void add (int k, Item x) { L.add (L.size ()-k, x); } public Item set (int k, Item x) { return L.set (L.size ()-k-1, x); } public Item remove (int k) { return L.remove (L.size () - k - 1); } }
ArrayList
– Advantages: compact, fast random access (indexing).
– Disadvantages: insertion, deletion can be slow— 好处:
- 紧凑的空间利用,比其包含的所有元素所占空间总量要小
- 随机获取元素快(Θ(1)),常数时间完成操作
— 坏处:
在最坏情况下,改变序列的操作非常缓慢(Θ(N))。
- 考虑A.read(x),也就是A.add(A.size(), x),即在序列最后添加元素。对于一个总容量为K的ArrayList,如果当存储元素达到总容量时,总容量扩大1,则有成本:
于是最差情况下有:
有点没写清楚,应该是Θ(M0 + (M0 + 1) + ... + (M0 + N))
- 换一种方法,如果到达总容量时,容量扩一倍,则有成本:
我们利用势能分析法(potential method),构造一个势能公式,势能必然与添加元素个数i,容量Si,原容量S0有关,满足:
ai + b (Si - S0)
必须满足,势能起点为0,势能必然大于0。所以可以构造出:
因为2i > Si ,所以满足大于等于0。
当i < Si 时,有:
当i = Si 时,有:
可见分摊成本是常数。
单链表(Singly Linked Lists)
简单实现:
class Entry { Entry (Object head, Entry next) { this.head = head; this.next = next; } Object head; Entry next; }
Changing the structure of a linked list (its set of containers) involves what is colloquially known as “pointer swinging.”
改变其数据结构,要使用被俗称为“摇曳的指针”(正如你所见到的,这是我胡起的)的手段。
“哨兵”(Sentinels)技术:
通常我们用这种方式添加链表:
L = L.next; L = new Entry ("aardvark", L);
但这样子头部的时候有所差别,所以我们添加一个“哨兵”节点来解决头部的差异性:
然后我们这要返回除掉哨兵节点的链表就可以了。
单链表好处:
- 简单创建,操作方便
单链表坏处:
- 被迫只能从头部迭代到当前位置,没有较快的方法到当前位置
- 要删除当前位置的元素,我们需要前一个元素的指针,但单链表没这东东
于是我们添加一个向前的指针来解决这个问题。
特殊列表
堆栈(Stack):先进的后出,从头部进从头部出。
队列(Queue):先进的先出,从头部进从尾部出。
双端列表(Deque):那边进出都可以。
相关资料
Data Structures (Into Java) . Paul N. Hilfinger
Potential method . Wiki
数据结构(算法艺术) . 刘汝佳