Java工具包提供了強大的數(shù)據(jù)結(jié)構(gòu)。在Java中的數(shù)據(jù)結(jié)構(gòu)主要包括以下幾種接口和類:
- 枚舉(Enumeration)
- 位集合(BitSet)
- 向量(Vector)
- 棧(Stack)
- 字典(Dictionary)
- 哈希表(Hashtable)
- 屬性(Properties)
枚舉(Enumeration)
枚舉(Enumeration)接口雖然它本身不屬于數(shù)據(jù)結(jié)構(gòu),但它在其他數(shù)據(jù)結(jié)構(gòu)的范疇里應用很廣。 枚舉(The Enumeration)接口定義了一種從數(shù)據(jù)結(jié)構(gòu)中取回連續(xù)元素的方式。
例如,枚舉定義了一個叫nextElement 的方法,該方法用來得到一個包含多元素的數(shù)據(jù)結(jié)構(gòu)的下一個元素。
Enumeration接口中定義了一些方法,通過這些方法可以枚舉(一次獲得一個)對象集合中的元素。
這種傳統(tǒng)接口已被迭代器取代,雖然Enumeration 還未被遺棄,但在現(xiàn)代代碼中已經(jīng)被很少使用了。盡管如此,它還是使用在諸如Vector和Properties這些傳統(tǒng)類所定義的方法中,除此之外,還用在一些API類,并且在應用程序中也廣泛被使用。
以下實例演示了Enumeration的使用:
import java.util.Vector;
import java.util.Enumeration;
public class EnumerationTester {
public static void main(String args[]) {
Enumeration<String> days;
Vector<String> dayNames = new Vector<String>();
dayNames.add("Sunday");
dayNames.add("Monday");
dayNames.add("Tuesday");
dayNames.add("Wednesday");
dayNames.add("Thursday");
dayNames.add("Friday");
dayNames.add("Saturday");
days = dayNames.elements();
while (days.hasMoreElements()){
System.out.println(days.nextElement());
}
}
}
以上實例編譯運行結(jié)果如下:
Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
位集合(BitSet)
位集合類實現(xiàn)了一組可以單獨設置和清除的位或標志。
該類在處理一組布爾值的時候非常有用,你只需要給每個值賦值一"位",然后對位進行適當?shù)脑O置或清除,就可以對布爾值進行操作了。
一個Bitset類創(chuàng)建一種特殊類型的數(shù)組來保存位值。BitSet中數(shù)組大小會隨需要增加。這和位向量(vector of bits)比較類似。
這是一個傳統(tǒng)的類,但它在Java 2中被完全重新設計。
BitSet定義了兩個構(gòu)造方法。
第一個構(gòu)造方法創(chuàng)建一個默認的對象:
BitSet()
第二個方法允許用戶指定初始大小。所有位初始化為0。
BitSet(int size)
下面的程序說明這個數(shù)據(jù)結(jié)構(gòu)支持的幾個方法:
import java.util.BitSet;
public class BitSetDemo {
public static void main(String args[]) {
BitSet bits1 = new BitSet(16);
BitSet bits2 = new BitSet(16);
// set some bits
for(int i=0; i<16; i++) {
if((i%2) == 0) bits1.set(i);
if((i%5) != 0) bits2.set(i);
}
System.out.println("Initial pattern in bits1: ");
System.out.println(bits1);
System.out.println("\nInitial pattern in bits2: ");
System.out.println(bits2);
// AND bits
bits2.and(bits1);
System.out.println("\nbits2 AND bits1: ");
System.out.println(bits2);
// OR bits
bits2.or(bits1);
System.out.println("\nbits2 OR bits1: ");
System.out.println(bits2);
// XOR bits
bits2.xor(bits1);
System.out.println("\nbits2 XOR bits1: ");
System.out.println(bits2);
}
}
以上實例編譯運行結(jié)果如下:
Initial pattern in bits1:
{0, 2, 4, 6, 8, 10, 12, 14}
Initial pattern in bits2:
{1, 2, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14}
bits2 AND bits1:
{2, 4, 6, 8, 12, 14}
bits2 OR bits1:
{0, 2, 4, 6, 8, 10, 12, 14}
bits2 XOR bits1:
{}
向量(Vector)
向量(Vector)類和傳統(tǒng)數(shù)組非常相似,但是Vector的大小能根據(jù)需要動態(tài)的變化。
和數(shù)組一樣,Vector對象的元素也能通過索引訪問。
使用Vector類最主要的好處就是在創(chuàng)建對象的時候不必給對象指定大小,它的大小會根據(jù)需要動態(tài)的變化。
Vector類實現(xiàn)了一個動態(tài)數(shù)組。和ArrayList和相似,但是兩者是不同的:
- Vector是同步訪問的。
- Vector包含了許多傳統(tǒng)的方法,這些方法不屬于集合框架。
Vector主要用在事先不知道數(shù)組的大小,或者只是需要一個可以改變大小的數(shù)組的情況。
Vector類支持4種構(gòu)造方法。
第一種構(gòu)造方法創(chuàng)建一個默認的向量,默認大小為10:
Vector()
第二種構(gòu)造方法創(chuàng)建指定大小的向量。
Vector(int size)
第三種構(gòu)造方法創(chuàng)建指定大小的向量,并且增量用incr指定. 增量表示向量每次增加的元素數(shù)目。
Vector(int size,int incr)
第四種構(gòu)造方法創(chuàng)建一個包含集合c元素的向量:
Vector(Collection c)
下面的程序說明這個集合所支持的幾種方法:
import java.util.*;
public class VectorDemo {
public static void main(String args[]) {
// initial size is 3, increment is 2
Vector v = new Vector(3, 2);
System.out.println("Initial size: " + v.size());
System.out.println("Initial capacity: " +
v.capacity());
v.addElement(new Integer(1));
v.addElement(new Integer(2));
v.addElement(new Integer(3));
v.addElement(new Integer(4));
System.out.println("Capacity after four additions: " +
v.capacity());
v.addElement(new Double(5.45));
System.out.println("Current capacity: " +
v.capacity());
v.addElement(new Double(6.08));
v.addElement(new Integer(7));
System.out.println("Current capacity: " +
v.capacity());
v.addElement(new Float(9.4));
v.addElement(new Integer(10));
System.out.println("Current capacity: " +
v.capacity());
v.addElement(new Integer(11));
v.addElement(new Integer(12));
System.out.println("First element: " +
(Integer)v.firstElement());
System.out.println("Last element: " +
(Integer)v.lastElement());
if(v.contains(new Integer(3)))
System.out.println("Vector contains 3.");
// enumerate the elements in the vector.
Enumeration vEnum = v.elements();
System.out.println("\nElements in vector:");
while(vEnum.hasMoreElements())
System.out.print(vEnum.nextElement() + " ");
System.out.println();
}
}
以上實例編譯運行結(jié)果如下:
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.45 6.08 7 9.4 10 11 12
棧(Stack)
棧(Stack)實現(xiàn)了一個后進先出(LIFO)的數(shù)據(jù)結(jié)構(gòu)。
你可以把棧理解為對象的垂直分布的棧,當你添加一個新元素時,就將新元素放在其他元素的頂部。
當你從棧中取元素的時候,就從棧頂取一個元素。換句話說,最后進棧的元素最先被取出。
棧是Vector的一個子類,它實現(xiàn)了一個標準的后進先出的棧。
堆棧只定義了默認構(gòu)造函數(shù),用來創(chuàng)建一個空棧。 堆棧除了包括由Vector定義的所有方法,也定義了自己的一些方法。
Stack()
下面的程序說明這個集合所支持的幾種方法
import java.util.*;
public class StackDemo {
static void showpush(Stack<Integer> st, int a) {
st.push(new Integer(a));
System.out.println("push(" + a + ")");
System.out.println("stack: " + st);
}
static void showpop(Stack<Integer> st) {
System.out.print("pop -> ");
Integer a = (Integer) 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");
}
}
}
以上實例編譯運行結(jié)果如下:
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
字典(Dictionary)
字典(Dictionary) 類是一個抽象類,它定義了鍵映射到值的數(shù)據(jù)結(jié)構(gòu)。
當你想要通過特定的鍵而不是整數(shù)索引來訪問數(shù)據(jù)的時候,這時候應該使用Dictionary。
由于Dictionary類是抽象類,所以它只提供了鍵映射到值的數(shù)據(jù)結(jié)構(gòu),而沒有提供特定的實現(xiàn)。
Dictionary 類是一個抽象類,用來存儲鍵/值對,作用和Map類相似。
給出鍵和值,你就可以將值存儲在Dictionary對象中。一旦該值被存儲,就可以通過它的鍵來獲取它。所以和Map一樣, Dictionary 也可以作為一個鍵/值對列表。
Dictionary類已經(jīng)過時了。在實際開發(fā)中,你可以實現(xiàn)Map接口來獲取鍵/值的存儲功能。
Java Map 接口
Map接口中鍵和值一一映射. 可以通過鍵來獲取值。
- 給定一個鍵和一個值,你可以將該值存儲在一個Map對象. 之后,你可以通過鍵來訪問對應的值。
- 當訪問的值不存在的時候,方法就會拋出一個NoSuchElementException異常.
- 當對象的類型和Map里元素類型不兼容的時候,就會拋出一個 ClassCastException異常。
- 當在不允許使用Null對象的Map中使用Null對象,會拋出一個NullPointerException 異常。
- 當嘗試修改一個只讀的Map時,會拋出一個UnsupportedOperationException異常。
下面的例子來解釋Map的功能
import java.util.*;
public class CollectionsDemo {
public static void main(String[] args) {
Map m1 = new HashMap();
m1.put("Zara", "8");
m1.put("Mahnaz", "31");
m1.put("Ayan", "12");
m1.put("Daisy", "14");
System.out.println();
System.out.println(" Map Elements");
System.out.print("\t" + m1);
}
}
以上實例編譯運行結(jié)果如下:
Map Elements
{Mahnaz=31, Ayan=12, Daisy=14, Zara=8}
哈希表(Hashtable)
Hashtable類提供了一種在用戶定義鍵結(jié)構(gòu)的基礎上來組織數(shù)據(jù)的手段。
例如,在地址列表的哈希表中,你可以根據(jù)郵政編碼作為鍵來存儲和排序數(shù)據(jù),而不是通過人名。
哈希表鍵的具體含義完全取決于哈希表的使用情景和它包含的數(shù)據(jù)。
Hashtable是原始的java.util的一部分, 是一個Dictionary具體的實現(xiàn) 。
然而,Java 2 重構(gòu)的Hashtable實現(xiàn)了Map接口,因此,Hashtable現(xiàn)在集成到了集合框架中。它和HashMap類很相似,但是它支持同步。
像HashMap一樣,Hashtable在哈希表中存儲鍵/值對。當使用一個哈希表,要指定用作鍵的對象,以及要鏈接到該鍵的值。
然后,該鍵經(jīng)過哈希處理,所得到的散列碼被用作存儲在該表中值的索引。
Hashtable定義了四個構(gòu)造方法。第一個是默認構(gòu)造方法:
Hashtable()
第二個構(gòu)造函數(shù)創(chuàng)建指定大小的哈希表:
Hashtable(int size)
第三個構(gòu)造方法創(chuàng)建了一個指定大小的哈希表,并且通過fillRatio指定填充比例。
填充比例必須介于0.0和1.0之間,它決定了哈希表在重新調(diào)整大小之前的充滿程度:
Hashtable(int size,float fillRatio)
第四個構(gòu)造方法創(chuàng)建了一個以M中元素為初始化元素的哈希表。
哈希表的容量被設置為M的兩倍。
Hashtable(Map m)
下面的程序說明這個數(shù)據(jù)結(jié)構(gòu)支持的幾個方法:
import java.util.*;
public class HashTableDemo {
public static void main(String args[]) {
// Create a hash map
Hashtable balance = new Hashtable();
Enumeration names;
String str;
double bal;
balance.put("Zara", new Double(3434.34));
balance.put("Mahnaz", new Double(123.22));
balance.put("Ayan", new Double(1378.00));
balance.put("Daisy", new Double(99.22));
balance.put("Qadir", new Double(-19.08));
// Show all balances in hash table.
names = balance.keys();
while(names.hasMoreElements()) {
str = (String) names.nextElement();
System.out.println(str + ": " +
balance.get(str));
}
System.out.println();
// Deposit 1,000 into Zara's account
bal = ((Double)balance.get("Zara")).doubleValue();
balance.put("Zara", new Double(bal+1000));
System.out.println("Zara's new balance: " +
balance.get("Zara"));
}
}
以上實例編譯運行結(jié)果如下:
Qadir: -19.08
Zara: 3434.34
Mahnaz: 123.22
Daisy: 99.22
Ayan: 1378.0
Zara's new balance: 4434.34
屬性(Properties)
Properties 繼承于 Hashtable.Properties 類表示了一個持久的屬性集.屬性列表中每個鍵及其對應值都是一個字符串。
Properties 類被許多Java類使用。例如,在獲取環(huán)境變量時它就作為System.getProperties()方法的返回值。
Properties 繼承于 Hashtable.表示一個持久的屬性集.屬性列表中每個鍵及其對應值都是一個字符串。
Properties 類被許多Java類使用。例如,在獲取環(huán)境變量時它就作為System.getProperties()方法的返回值。
Properties 定義如下實例變量.這個變量持有一個Properties對象相關的默認屬性列表。
Properties defaults;
Properties類定義了兩個構(gòu)造方法. 第一個構(gòu)造方法沒有默認值。
Properties()
第二個構(gòu)造方法使用propDefault 作為默認值。兩種情況下,屬性列表都為空:
Properties(Properties propDefault)
下面的程序說明這個數(shù)據(jù)結(jié)構(gòu)支持的幾個方法:
import java.util.*;
public class PropDemo {
public static void main(String args[]) {
Properties capitals = new Properties();
Set states;
String str;
capitals.put("Illinois", "Springfield");
capitals.put("Missouri", "Jefferson City");
capitals.put("Washington", "Olympia");
capitals.put("California", "Sacramento");
capitals.put("Indiana", "Indianapolis");
// Show all states and capitals in hashtable.
states = capitals.keySet(); // get set-view of keys
Iterator itr = states.iterator();
while(itr.hasNext()) {
str = (String) itr.next();
System.out.println("The capital of " +
str + " is " + capitals.getProperty(str) + ".");
}
System.out.println();
// look for state not in list -- specify default
str = capitals.getProperty("Florida", "Not Found");
System.out.println("The capital of Florida is "
+ str + ".");
}
}
以上實例編譯運行結(jié)果如下:
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.
迭代器 iterator 用法
Java 中的 Iterator 功能比較簡單,并且只能單向移動:
(1) 使用方法 iterator() 要求容器返回一個 Iterator。第一次調(diào)用 Iterator 的 next() 方法時,它返回序列的第一個元素。注意:iterator() 方法是 java.lang.Iterable 接口,被 Collection 繼承。
(2) 使用 next() 獲得序列中的下一個元素。
(3) 使用 hasNext() 檢查序列中是否還有元素。
(4) 使用 remove() 將迭代器新返回的元素刪除。