Java 數(shù)據(jù)結(jié)構(gòu)

Java工具包提供了強(qiáng)大的數(shù)據(jù)結(jié)構(gòu)。在Java中的數(shù)據(jù)結(jié)構(gòu)主要包括以下幾種接口和類:

  1. 枚舉(Enumeration)
  2. 位集合(BitSet)
  3. 向量(Vector)
  4. 棧(Stack)
  5. 字典(Dictionary)
  6. 哈希表(Hashtable)
  7. 屬性(Properties)

枚舉(Enumeration)

枚舉(Enumeration)接口雖然它本身不屬于數(shù)據(jù)結(jié)構(gòu),但它在其他數(shù)據(jù)結(jié)構(gòu)的范疇里應(yīng)用很廣。 枚舉(The Enumeration)接口定義了一種從數(shù)據(jù)結(jié)構(gòu)中取回連續(xù)元素的方式。

例如,枚舉定義了一個(gè)叫nextElement 的方法,該方法用來(lái)得到一個(gè)包含多元素的數(shù)據(jù)結(jié)構(gòu)的下一個(gè)元素。

Enumeration接口中定義了一些方法,通過(guò)這些方法可以枚舉(一次獲得一個(gè))對(duì)象集合中的元素。

這種傳統(tǒng)接口已被迭代器取代,雖然Enumeration 還未被遺棄,但在現(xiàn)代代碼中已經(jīng)被很少使用了。盡管如此,它還是使用在諸如Vector和Properties這些傳統(tǒng)類所定義的方法中,除此之外,還用在一些API類,并且在應(yīng)用程序中也廣泛被使用。

以下實(shí)例演示了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()); 
      }
   }
}

以上實(shí)例編譯運(yùn)行結(jié)果如下:

Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday

位集合(BitSet)

位集合類實(shí)現(xiàn)了一組可以單獨(dú)設(shè)置和清除的位或標(biāo)志。

該類在處理一組布爾值的時(shí)候非常有用,你只需要給每個(gè)值賦值一"位",然后對(duì)位進(jìn)行適當(dāng)?shù)脑O(shè)置或清除,就可以對(duì)布爾值進(jìn)行操作了。

一個(gè)Bitset類創(chuàng)建一種特殊類型的數(shù)組來(lái)保存位值。BitSet中數(shù)組大小會(huì)隨需要增加。這和位向量(vector of bits)比較類似。

這是一個(gè)傳統(tǒng)的類,但它在Java 2中被完全重新設(shè)計(jì)。

BitSet定義了兩個(gè)構(gòu)造方法。

第一個(gè)構(gòu)造方法創(chuàng)建一個(gè)默認(rèn)的對(duì)象:

BitSet()

第二個(gè)方法允許用戶指定初始大小。所有位初始化為0。

BitSet(int size)

下面的程序說(shuō)明這個(gè)數(shù)據(jù)結(jié)構(gòu)支持的幾個(gè)方法:

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);
  }
}

以上實(shí)例編譯運(yùn)行結(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ù)需要?jiǎng)討B(tài)的變化。

和數(shù)組一樣,Vector對(duì)象的元素也能通過(guò)索引訪問(wèn)。

使用Vector類最主要的好處就是在創(chuàng)建對(duì)象的時(shí)候不必給對(duì)象指定大小,它的大小會(huì)根據(jù)需要?jiǎng)討B(tài)的變化。

Vector類實(shí)現(xiàn)了一個(gè)動(dòng)態(tài)數(shù)組。和ArrayList和相似,但是兩者是不同的:

  1. Vector是同步訪問(wèn)的。
  2. Vector包含了許多傳統(tǒng)的方法,這些方法不屬于集合框架。

Vector主要用在事先不知道數(shù)組的大小,或者只是需要一個(gè)可以改變大小的數(shù)組的情況。

Vector類支持4種構(gòu)造方法。

第一種構(gòu)造方法創(chuàng)建一個(gè)默認(rèn)的向量,默認(rèn)大小為10:

Vector()

第二種構(gòu)造方法創(chuàng)建指定大小的向量。

Vector(int size)

第三種構(gòu)造方法創(chuàng)建指定大小的向量,并且增量用incr指定. 增量表示向量每次增加的元素?cái)?shù)目。

Vector(int size,int incr)

第四種構(gòu)造方法創(chuàng)建一個(gè)包含集合c元素的向量:

Vector(Collection c)

下面的程序說(shuō)明這個(gè)集合所支持的幾種方法:

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();
   }
}

以上實(shí)例編譯運(yùn)行結(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)實(shí)現(xiàn)了一個(gè)后進(jìn)先出(LIFO)的數(shù)據(jù)結(jié)構(gòu)。

你可以把棧理解為對(duì)象的垂直分布的棧,當(dāng)你添加一個(gè)新元素時(shí),就將新元素放在其他元素的頂部。

當(dāng)你從棧中取元素的時(shí)候,就從棧頂取一個(gè)元素。換句話說(shuō),最后進(jìn)棧的元素最先被取出。

棧是Vector的一個(gè)子類,它實(shí)現(xiàn)了一個(gè)標(biāo)準(zhǔn)的后進(jìn)先出的棧。

堆棧只定義了默認(rèn)構(gòu)造函數(shù),用來(lái)創(chuàng)建一個(gè)空棧。 堆棧除了包括由Vector定義的所有方法,也定義了自己的一些方法。

Stack()

下面的程序說(shuō)明這個(gè)集合所支持的幾種方法

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");
        }
    }
}

以上實(shí)例編譯運(yùn)行結(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) 類是一個(gè)抽象類,它定義了鍵映射到值的數(shù)據(jù)結(jié)構(gòu)。

當(dāng)你想要通過(guò)特定的鍵而不是整數(shù)索引來(lái)訪問(wèn)數(shù)據(jù)的時(shí)候,這時(shí)候應(yīng)該使用Dictionary。

由于Dictionary類是抽象類,所以它只提供了鍵映射到值的數(shù)據(jù)結(jié)構(gòu),而沒(méi)有提供特定的實(shí)現(xiàn)。

Dictionary 類是一個(gè)抽象類,用來(lái)存儲(chǔ)鍵/值對(duì),作用和Map類相似。

給出鍵和值,你就可以將值存儲(chǔ)在Dictionary對(duì)象中。一旦該值被存儲(chǔ),就可以通過(guò)它的鍵來(lái)獲取它。所以和Map一樣, Dictionary 也可以作為一個(gè)鍵/值對(duì)列表。

Dictionary類已經(jīng)過(guò)時(shí)了。在實(shí)際開(kāi)發(fā)中,你可以實(shí)現(xiàn)Map接口來(lái)獲取鍵/值的存儲(chǔ)功能。

Java Map 接口

Map接口中鍵和值一一映射. 可以通過(guò)鍵來(lái)獲取值。

  1. 給定一個(gè)鍵和一個(gè)值,你可以將該值存儲(chǔ)在一個(gè)Map對(duì)象. 之后,你可以通過(guò)鍵來(lái)訪問(wèn)對(duì)應(yīng)的值。
  2. 當(dāng)訪問(wèn)的值不存在的時(shí)候,方法就會(huì)拋出一個(gè)NoSuchElementException異常.
  3. 當(dāng)對(duì)象的類型和Map里元素類型不兼容的時(shí)候,就會(huì)拋出一個(gè) ClassCastException異常。
  4. 當(dāng)在不允許使用Null對(duì)象的Map中使用Null對(duì)象,會(huì)拋出一個(gè)NullPointerException 異常。
  5. 當(dāng)嘗試修改一個(gè)只讀的Map時(shí),會(huì)拋出一個(gè)UnsupportedOperationException異常。

下面的例子來(lái)解釋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);
   }
}

以上實(shí)例編譯運(yùn)行結(jié)果如下:

Map Elements
        {Mahnaz=31, Ayan=12, Daisy=14, Zara=8}

哈希表(Hashtable)

Hashtable類提供了一種在用戶定義鍵結(jié)構(gòu)的基礎(chǔ)上來(lái)組織數(shù)據(jù)的手段。

例如,在地址列表的哈希表中,你可以根據(jù)郵政編碼作為鍵來(lái)存儲(chǔ)和排序數(shù)據(jù),而不是通過(guò)人名。

哈希表鍵的具體含義完全取決于哈希表的使用情景和它包含的數(shù)據(jù)。

Hashtable是原始的java.util的一部分, 是一個(gè)Dictionary具體的實(shí)現(xiàn) 。

然而,Java 2 重構(gòu)的Hashtable實(shí)現(xiàn)了Map接口,因此,Hashtable現(xiàn)在集成到了集合框架中。它和HashMap類很相似,但是它支持同步。

像HashMap一樣,Hashtable在哈希表中存儲(chǔ)鍵/值對(duì)。當(dāng)使用一個(gè)哈希表,要指定用作鍵的對(duì)象,以及要鏈接到該鍵的值。

然后,該鍵經(jīng)過(guò)哈希處理,所得到的散列碼被用作存儲(chǔ)在該表中值的索引。

Hashtable定義了四個(gè)構(gòu)造方法。第一個(gè)是默認(rèn)構(gòu)造方法:

Hashtable()

第二個(gè)構(gòu)造函數(shù)創(chuàng)建指定大小的哈希表:

Hashtable(int size)

第三個(gè)構(gòu)造方法創(chuàng)建了一個(gè)指定大小的哈希表,并且通過(guò)fillRatio指定填充比例。

填充比例必須介于0.0和1.0之間,它決定了哈希表在重新調(diào)整大小之前的充滿程度:

Hashtable(int size,float fillRatio)

第四個(gè)構(gòu)造方法創(chuàng)建了一個(gè)以M中元素為初始化元素的哈希表。

哈希表的容量被設(shè)置為M的兩倍。

Hashtable(Map m)

下面的程序說(shuō)明這個(gè)數(shù)據(jù)結(jié)構(gòu)支持的幾個(gè)方法:

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"));
   }
}

以上實(shí)例編譯運(yùn)行結(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 類表示了一個(gè)持久的屬性集.屬性列表中每個(gè)鍵及其對(duì)應(yīng)值都是一個(gè)字符串。

Properties 類被許多Java類使用。例如,在獲取環(huán)境變量時(shí)它就作為System.getProperties()方法的返回值。

Properties 繼承于 Hashtable.表示一個(gè)持久的屬性集.屬性列表中每個(gè)鍵及其對(duì)應(yīng)值都是一個(gè)字符串。

Properties 類被許多Java類使用。例如,在獲取環(huán)境變量時(shí)它就作為System.getProperties()方法的返回值。

Properties 定義如下實(shí)例變量.這個(gè)變量持有一個(gè)Properties對(duì)象相關(guān)的默認(rèn)屬性列表。

Properties defaults;

Properties類定義了兩個(gè)構(gòu)造方法. 第一個(gè)構(gòu)造方法沒(méi)有默認(rèn)值。

Properties()

第二個(gè)構(gòu)造方法使用propDefault 作為默認(rèn)值。兩種情況下,屬性列表都為空:

Properties(Properties propDefault)

下面的程序說(shuō)明這個(gè)數(shù)據(jù)結(jié)構(gòu)支持的幾個(gè)方法:

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 + ".");
   }
}

以上實(shí)例編譯運(yùn)行結(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 功能比較簡(jiǎn)單,并且只能單向移動(dòng):
(1) 使用方法 iterator() 要求容器返回一個(gè) Iterator。第一次調(diào)用 Iterator 的 next() 方法時(shí),它返回序列的第一個(gè)元素。注意:iterator() 方法是 java.lang.Iterable 接口,被 Collection 繼承。
(2) 使用 next() 獲得序列中的下一個(gè)元素。
(3) 使用 hasNext() 檢查序列中是否還有元素。
(4) 使用 remove() 將迭代器新返回的元素刪除。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容