JDK 源码解析 —— 集合框架

转载自:Java集合框架实例

1- 介绍

集合是程序和语言的基本思想。应用程序通常都会应用到集合,例如雇员的信息,图像的收集等的存储。像其他语言,Java还支持数组作为最基本的集合。然而,数组在许多情况下工作并不是那么方便,因为数组生命周期,增加元素或移除元素是非常困难的,甚至需要程序付出效率。

下图说明了一个数组的操作:

2- 第一个示例

首先,我们有链表(LinkedList)的例子。它是元素数不像数组一样限制的多变列表。

HelloLinkedList.java

package com.yiibai.tutorial.javacollection.helloworld;

import java.util.LinkedList;

public class HelloLinkedList {

    public static void main(String[] args) {

        // Create collection object - LinkedList

        LinkedList list = new LinkedList();

        // Add elements to the linked list

        list.add("F");

        list.add("B");

        list.add("D");

        list.add("E");

        list.add("C");


        // Appends the specified element to the end of this list.

        list.addLast("Z");

        list.addFirst("A");

        // Inserts the specified element at the beginning of this list.

        list.add(1, "A2");

        // Print out, all elements

        System.out.println("Original contents of list: " + list);

        // Remove elements from the linked list

        list.remove("F");

        // Remove the element at index 2.

        list.remove(2);

        // Print out the list, after removing two elements.

        System.out.println("Contents of list after deletion: " + list);

        // Remove first and last elements

        list.removeFirst();

        list.removeLast();


        // Print out collection

        System.out.println("List after deleting first and last: " + list);

        // Get and set a value

        Object val = list.get(2);


        // Set element at index 2

        list.set(2, (String) val + " Changed");

        System.out.println("List after change: " + list);

    }

}

运行示例的结果:

使用HashMap的一个例子。这是一种含有对的键/值的对象。考虑一个实例:电话簿,电话号码是一个键,同时用户的信息是一个值。键必须是不一样的。

HelloHashMap.java

package com.yiibai.tutorial.javacollection.helloworld;

import java.util.HashMap;

public class HelloHashMap {

    public static void main(String[] args) {


        // Create a HashMap objects, store employee-code and salaries.

        // String key: Employee-code

        // Float value: Salary

        HashMap salaryMap = new HashMap();


        salaryMap.put("E01", 1000f);

        salaryMap.put("E02", 12000f);

        salaryMap.put("E03", 12300f);

        salaryMap.put("E04", 1000f);

        salaryMap.put("E05", 300.5f);


        // Get the salary of employee 'E02'

        Float salary= salaryMap.get("E01");

        System.out.println("Salary of employee E01 = "+ salary);


        // Change the salary for employee 'E05'

        salaryMap.put("E05", 400f);


        System.out.println("Salary of employee E05 = "+ salaryMap.get("E05"));


    }

}

运行示例的结果:

Salary of employee E01 = 1000.0

Salary of employee E05 = 400.0

3- 使用数组的局限性 - 一个建议来解决这个问题

3.1- 数组是一个基本的集合类型

数组是非常基本的也是大家最熟悉的。

存储引用类型,基本类型

int[] myArray=new int[]{1,4,3};

Object[] myArrayObj =new Object[]{"Object",new Integer(100)};

数组具有固定的大小和尺寸。

这使得数组难以扩展

元件排列并顺序地引用在内存中。

这使得难以从数组中删除指定的元素。

3.2- 从数组中删除元素

数组中的元素是连续排列在内存中的,所以如果你有意数组要删除一个元素是比较困难的,因为它会失去了延续性。通常情况下,在技术上创建一个新的数组是存储上次的数组对象并丢弃不必要的元素,但这种降低了程序的执行效率。类似的技术被应用到数组的扩展,在此我们会以更大的空间来创建一个新的数组,然后将之前的数组元素复制到新的的数组。

显然,这种数组应用在应用程序中在许多情况下不是好方法。

3.3- 链表

链表是克服的数组的弱点数据管理方式之一。当然,也有在Java管理列表的各种方法,例如:ArrayList

让我们来看看链表(LinkedList)的特点: 

在这个列表中的元素可以在存储器中,不连续地分离出来。

它是元素间双向链路。

列表中的每个元素,使它前面的元素和它后面的元素的引用。

链表是一个双向链路。

链接元素是需要管理一个包含对象的数据。它有两个引用链接元素的前面和后面。

就像一群人在排队,每个人需要记住两个人 - 站面前和在后面他/她。

移除LinkedList的一个元素

移除LinkedList的一个元素是一样的去除类似站在队列的人。 靠近此人两个人不得不重新更新的人面前,背后的人。

添加元素到链表中(在末尾或在链表中)

总之,虽然我们只是有一个链表的例子,它可以帮助我们理解java.util包更多的信息。

注:链表方案是解决数组的一个弱点。 ArrayList是管理数据集合的方法。它可以处理数组的弱点,但它管理数据的方式与LinkedList是不同的。

4- Java Collections框架概述

意识到数组局限性,从版本Java1.0就有java.util.Vector,是对象的类存储列表。 java.util.Hashtable是一个存储对键/值的类。其次,Java 2平台仍在不断推出接近集合的方式,命名为集合框架。java.util.Vector,java.util.Hashtable依然存在,现在是巨大的平台的一部分。 这些集合都建在java.util包中一些接口的基础上。它们被分成由2个接口主导两个层次结构系统,java.util.Collection包含对象和键/值对的java.util.Map列表。

4.1- Java集合框架接口

上面的图片是Java Collections Framework的重要接口。我们将把它们按用途和用法讨论这些接口的使用目的。在java.util包,类实现一个或多个这些接口。 因此,java.util中的类可以具有许多不同的功能。例如,java.util.HashMap:

Class Hashtable:

public class HashMap extends AbstractMap

                          implements Map, Cloneable, Serializable

Class Vector:

public class Vector extends AbstractList

            implements List, RandomAccess, Cloneable, Serializable

4.2- 接口集合和映射引导两个层次- 数据存储方法

集合组存储对象。

在集合组三个子分支: Queue, List, 和 Set.

元素可以是相似或不相似这取决于它们的分支。 (更多细节将在后面讨论)。

映射组存储key和value对

映射的键是不允许相同的。

如果我们知道键,就可以提取等于其映射键对应的值。

在引用类型的形式集合组存储数据,MAP组存储对键和值。

Collection c=new ArrayList();

// Add elements to collection

c.add("One");

Map m=new LinkedHashMap();

Integer key=new Integer(123);

String value="One two three";

// Associates the specified value with the specified key in this map.

// If the map previously contained a mapping for the key, the old

// value is replaced.

m.put(key,value);

//

System.out.println(m.get(new Integer(123));

4.3- 接口迭代器和随机访问 - 数据访问方法

java.util.Iterator

要检索数据,从一个元素到另一个元素依次访问迭代器。

java.util.RandomAccess

随机接入方法,例如定位元素和设定检索该元素

例如,java.util.Vector实现了这个接口,可以检索随机元素使用vector.get (int index)。

集合组也可以反过来通过调用方法iterator() 来检索访问Iterator对象。

java.util.Collection接口是从java.lang.Iterable扩展,所以它继承了public Iterator iterator() 方法,来迭代集合的元素。

在上述2个接口迭代器和随机访问的示例,它代表了两种方法如何访问一个集合中的元素。

看看 Vector 类:

public class Vector extends AbstractList

              implements List, RandomAccess, Cloneable, Serializable

Vector属于集合组,可以通过get (index) 方法访问,或通过迭代器,或随机访问来元素。

注:对于列表组类,也可以检索对象的ListIterator, 这个迭代器可以让你在列表中向后或向前仅向前的光标位置,而不是像迭代器一样。

5- 集合组

5.1- 集合组中的接口

集合有三种直接子接口:Queue,List和Set。其中,Queue从1.5版本中增加,并考虑为这是一个等待队列。Queue也有一个子接口:BlockingQueue,属于java.util.concurrent包, 但我们没有在这节教程中讨论。Queue是一个包含许多定义以及组织我们需要最注重的接口方式。三个接口Queue , List , Set被视为集合组的三个分支。

在学习这几个组的细节之前,让我们来看看Collection接口的概述。

5.2- java.util.Collection接口

继承关系

java.util.Collection

public interface Collection extends java.lang.Iterable {

  //

  // Add element to collection

  // return true if this collection changed as a result of the call

  //

  boolean add(E o);

  //

  // Adds all of the elements in the specified collection to this collection.

  // return true if this collection changed as a result of the call

  //

  boolean addAll(Collection c);

  // Removes all of the elements from this collection (optional operation).

  // The collection will be empty after this method returns.

  void clear();

  // Returns true if this collection contains the specified element.

  boolean contains(Object o);

  // Returns true if this collection contains all of the elements

  // in the specified collection.

  boolean containsAll(Collection c);

  // Compares the specified object with this collection for equality

  boolean equals(Object o);

  int hashCode();

  // Returns true if this collection contains no elements.

  boolean isEmpty();

  //

  // Removes a single instance of the specified element from this

  // collection, if it is present (optional operation).

  //

  boolean remove(Object o);

  // Removes all of this collection's elements that are also contained in the

  // specified collection (optional operation)

  boolean removeAll(Collection c);

  //

  // Retains only the elements in this collection that are contained in the

  // specified collection (optional operation)

  //

  boolean retainAll(Collection c);

  // Returns the number of elements in this collection

  int size();

  // Returns an array containing all of the elements in this collection

  Object[] toArray();

  T[] toArray(T[] a);

  // Returns an iterator over the elements in this collection.

  Iterator iterator();

}

5.3- 访问集合中的元素

集合中的元素迭代器。

例如,使用迭代访问集合的元素。

CollectionAndIterator.java

package com.yiibai.tutorial.javacollection.collection;

import java.util.Collection;

import java.util.Iterator;

import java.util.Vector;

public class CollectionAndIterator {

    public static void main(String[] args) {


        // Create empty collection

        // A Collection containing only String.

        Collection coll = new Vector();

        coll.add("Collection");

        coll.add("Queue");

        coll.add("List");

        coll.add("Map");

        // Print out the number of elements in this collection

        System.out.println("Size:" + coll.size());

        // Returns an iterator over the elements in this collection.

        // This Iterator containing only String.

        Iterator ite = coll.iterator();



        // Returns true if the iteration has more elements

        while (ite.hasNext()) {

            // Returns the next element in the iteration.

            String s = ite.next();

            System.out.println("Element:" + s);

        }

    }

}

运行实例的结果:

Size:4

Element:Collection

Element:Queue

Element:List

Element:Map

5.4- 集合的分支

正如上面所说的,集合有三个子接口,包括Queue ,List 和 Set。它们之间的差别是存储数据的方式。

java.util.Queuejava.util.Listjava.util.Set

允许包含重复的元素允许包含重复的元素不允许重复的元素

不允许包含null元素允许包含一个或多个null元素根据不同的类实现Set接口,是否支持包含空元素。如果支持,它仅包含至多有一个null元素。

一个列表(List)的目的,是一个相同的对象很可能出现不止一次的有序列表。 例如 : [1, 7, 1, 3, 1, 1, 1, 5]. 说说在列表中的“第三个元素”是很有意义的。 可以在列表的任意位置添加元素,在列表中的任何位置更改元素,或从列表中的任何位置删除元素。

- 队列也是有顺序的,但你永远只能触及一端的元素。元素被插入在“结尾”,并从队列中的“开头”(或头部)删除。你可以知道在队列中有多少个元素,但不能找出说,“第三个”元素是什么。当你到达那里,你会看到它。

一个集合(Set)不是有序的,也不能包含重复的元素。任何给定的对象是不在集合中的。{7, 5, 3, 1} 集合是确实相同于 {1, 7, 1, 3, 1, 1, 1, 5}. 因此无法要求提供“第三个”元素,甚至“第一”的元素,因为它们不以任何特定的顺序。 您可以添加或删除元素,也可以找出某个元素是否存在(例如,“7在这一集合中?”)

5.5- java.util.List 接口

列表(List)是集合(Collection)的子接口。它拥有Collection的全部功能,以及一些特殊的功能:

允许重复元素

允许零个或多个null元素存在。

列表(List)是对象的有序列表

除了通过使用迭代访问,我们可以通过使用 ListIterator 访问。允许 ListIterator 向前或向后移动光标。

// Returns a list iterator over the elements in this list 

public ListIterator listIterator() của list .

// Returns a list iterator over the elements in this list (in proper

// sequence), starting at the specified position in the list..

public ListIterator listIterator(int index) :

ListAndListIterator.java

package com.yiibai.tutorial.javacollection.list;

import java.util.ArrayList;

import java.util.List;

import java.util.ListIterator;

public class ListAndListIterator {

    public static void main(String[] args) {

        // Create List object (Containing only String)

        List list = new ArrayList();

        list.add("One");

        list.add("Two");

        list.add("Three");

        list.add("Four");

        // Returns a list iterator over the elements in this list

        // (in proper sequence)

        ListIterator listIterator = list.listIterator();


        // Currently the cursor at the first position of the interator.

        // (Index 0).

        // Get the first element in the interator, the cursor forward one step.

        String first = listIterator.next();

        System.out.println("first:" + first);// -->"One"

        // Current cursor at index 1

        // Get next element.

        String second = listIterator.next();

        System.out.println("second:" + second);// -->"Two"

        // true if the list iterator has more elements when

        // traversing the list in the reverse direction

        if (listIterator.hasPrevious()) {

            // the previous element in the list

            String value = listIterator.previous();

            System.out.println("value:" + value);// -->"Two"

        }

        System.out.println(" ----- ");

        while (listIterator.hasNext()) {

            String value = listIterator.next();

            System.out.println("value:" + value);

        }

    }

}

运行实例的结果:

first:One

second:Two

value:Two

-----

value:Two

value:Three

value:Four

5.6- java.util.Set接口

Set是Collection的子接口。它拥有集合的全部功能,以及其他一些特点:

描述了一组不允许重复元素的集合

允许一个空元素的存在,如果有的话。

HashSetExample.java

package com.yiibai.tutorial.javacollection.set;

import java.util.HashSet;

import java.util.Iterator;

import java.util.Set;

public class HashSetExample {

    public static void main(String[] args) {


        // Create a Set object with initial capacity 10

        // Automatically increase capacity 80% if the number of elements to

        // overcome the current capacity.

        // HashSet (LIFO - Last in first out)

        //  (element to be added later will stand first).

        Set set = new HashSet(10, (float) 0.8);

        set.add("One");

        set.add("Two");


        // Duplication occurs.

        // With HashSet: It will add new element, and remove the old element.

        set.add("One");

        set.add("Three");

        Iterator it = set.iterator();

        while (it.hasNext()) {

            System.out.println(it.next());

        }

    }

}

运行实例的结果:

One

Two

Three

5.7- java.util.Queue接口

Queue是Collection的子类型的接口,它充满着集合的特点,相当类似于列表(List),但是,使用目的略有不同。队列(Queue)被设计成只能访问第一个元素(删除元素时)在队列中,它会删除队列的第一个元素。有点类似于人在超市排队一样,只有在队列的头部将可访问,新人如要插入到该队列中,插入位置可能不是队列的末尾。插入的元素位置取决于队列的类型和元素的优先级。

队列允许元素重复

不允许null元素

有两个类都实现了Queue接口:

java.util.LinkedList

java.util.PriorityQueue

LinkedList是一个非常标准的队列实现。但请记住,LinkedList同时实现List和Queue接口。

PriorityQueue根据自己的自然顺序存储的元素(如果它们实现Comparable)或者根据Comparator 传递给PriorityQueue。请注意,一个类可以实现了List 和Queue接口,所以你不需要关心元素是如何安排在上述内部类的,如果把它作为一个队列,请参阅访问队列中元素的方式。考虑队列的典型方法,它模拟人在超市排队队列。

抛出异常返回指定值

Insertadd(e)offer(e)

Removeremove()poll()

Examineelement()peek()

boolean add(E)

将指定的元素插入此队列中,如果它是立即可行且不违反容量限制,成功则返回true,如果当前没有空间可用则抛出IllegalStateException。

boolean offer(E)

将指定的元素插入此队列中,如果它是立即可行且不违反容量限制。当使用有容量限制的队列通常是使用 add(E)方法,它可能在无法插入的元素时抛出异常 。

E remove()

检索并移除此队列的头元素。该方法与poll不同在于如果此队列为空,它会抛出一个异常。

E poll()

检索,但是不移除此队列的头元素。这种方法与 peek 方法不同,如果此队列为空它抛出一个异常。

E element()

检索,但是不移除此队列的头元素。这种方法与peek方法不同,如果此队列为空它抛出一个异常。

E peek()

检索,但是不移除此队列的头元素,或者如果此队列为空则返回null。

解释:

除了上面提到的队列方法外,您可以在队列中访问其他元素,除了第一个元素,也不能指定将被插入元素的位置。

QueueDemo.java

package com.yiibai.tutorial.javacollection.queue;

import java.util.LinkedList;

import java.util.Queue;

public class QueueDemo {

    public static void main(String[] args) {

        Queue names = new LinkedList();


        // offer(E): Insert element to queue.

        // With LinkedList, element will inserted at the end of queue.

        // Return true if success.

        // Return false if queue full.

        names.offer("E");

        names.offer("A");

        names.offer("M");



        // add(E): Insert element to queue

        // With LinkedList, element will inserted at the end of queue.

        // Return true if success.

        // Throw exception if queue full.   

        names.add("G");

        names.add("B");

        while (true) {     


            // Retrieves and removes the head of this queue,

            // or returns null if this queue is empty.

            String name = names.poll();

            if (name == null) {

                break;

            }

            System.out.println("Name=" + name);

        }

    }

}

运行实例的结果:

Name=E

Name=A

Name=M

Name=G

Name=B

例如,使用一个优先队列PriorityQueue。此队列在内部根据自己的自然顺序(如果实现Comparable),或者根据传递给PriorityQueue比较器(Comparator )来存储它的元素。

String就是实现了Comparable接口的类,它们可以相互比较后并按字母顺序排列。

PriorityQueueDemo.java

package com.yiibai.tutorial.javacollection.queue;

import java.util.PriorityQueue;

import java.util.Queue;

public class PriorityQueueDemo {

    public static void main(String[] args) {


        // With PriorityQueue queue, the elements will be arranged on the natural order

        Queue names = new PriorityQueue();

        // offer(E): Insert element to queue

        // Return true if success

        // Return false if queue is full.

        names.offer("E");

        names.offer("A");

        names.offer("M");

        // add(E): Insert element to queue.

        // Return true if success

        // Throw exceptiono if queue is full.

        names.add("G");

        names.add("B");

        while (true) {


            // Retrieves and removes the head of this queue,

            // or returns null if this queue is empty.

            String name = names.poll();

            if (name == null) {

                break;

            }

            System.out.println("Name=" + name);

        }

    }

}

运行实例的结果:

Name=A

Name=B

Name=E

Name=G

Name=M

5.8- Collection组类之间的继承关系

一些常见的类:

实现

Hash TableResizable ArrayBalanced TreeLinked ListHash Table + Linked List

InterfacesSetHashSetTreeSetLinkedHashSet

ListArrayList

5.9- java.util.ArrayList

ArrayList拥有充分的List接口的功能。此外,它允许访问随机元素,由于继承了RandomAccess。

它基本上类似于Vector类。然而,虽然Vector方法是同步的,这些ArrayList都没有。 因此ArrayList适合于单线程的应用程序。

ArrayListDemo.java

package com.yiibai.tutorial.javacollection.list;

import java.util.ArrayList;

public class ArrayListDemo {

  public static void main(String[] args) {


      // Create an ArrayList object that contains the element Integer.

      ArrayList list = new ArrayList(10);


      // Add elements

      list.add(123);

      list.add(245);

      list.add(new Integer(345));


      // ArrayList allow add null elements.

      // (Feature of List)

      list.add(null);


      // Print out the number of elements in this list.

      System.out.println("Size:" + list.size());// =4


      // Random access to elements of index 1.

      Integer i = list.get(1);

      System.out.println("Element index 1 =" + i);// =245

      Integer newInt = 1000;


      // Replaces the element at the specified position

      // in this list with the specified element.

      Integer old = list.set(1, newInt);

      //

      System.out.println("Old value:" +old);// =245 .

      System.out.println("New value:" + list.get(1));// =1000 .

  }

}

运行实例的结果:

Size:4

Element index 1 =245

Old value:245

New value:1000

5.10- java.util.Vector

Vector是一个类,其功能类似于ArrayList。 所不同的是Vector 的方法同步,而ArrayList的方法不同步。

Vector 的方法是同步的,所以在多线程应用程序它运行良好。

Vector有一些是1.0版继承附加的方法,在Java提到集合框架的概念之前。

// Legacy method from 1.0, get element at index position

// Like get(index)

public E elementAt(int index)

// Method inherited from the List interface, get element at position index.

public E get(int index)

// Replaces the element at the specified position in this list with the specified element

// Return old element.

// setElementAt(int,E) like set(int,E)

public void setElementAt(int index, E element);

// Replaces the element at the specified position in this list with the specified element

// Return old element.

public E set(int index, E element)

VectorDemo.java

package com.yiibai.tutorial.javacollection.list;

import java.util.Vector;

public class VectorDemo {

    public static void main(String[] args) {

        // Create Vector object with capacity 10 (element)

        // Automatically increase capacity 5, if the number of elements to

        // overcome the current capacity.

        Vector v = new Vector(10, 5);

        v.add(123);

        v.add(245);

        v.add(new Integer(345));

        v.add(null);

        // Returns the number of elements in this vector. (Not capacity).

        System.out.println("Size:" + v.size());// =4

        // Get element at index 1

        // (like method get(int))

        Integer i = v.elementAt(1);

        System.out.println("v.elementAt(1)=" + i);// 245

        // Method này trả về phần tử cũ.


        // Set element at index 1,

        // and return old element at index 1.

        v.setElementAt(1, 1000);

        //

        System.out.println("New value:" + v.get(1));// =1000 .

    }

}

运行示例的结果:

5.11- java.util.SortedSet

SortedSet是Set接口的子类型的接口,它充满着Set的功能。SortedSet是具有一个有组织的Set类,加入到集合类新元素自动放在一个合适的位置,以确保集合仍在排列(升序或降序)。

因此,SortedSet的元素必须彼此进行比较,并且它们必须是java.lang.Comparable的对象(可以是comparable)。  

如果添加不是Comparable的元素到SortedSet对象,会得到一个异常。

类实现 SortedSet:  TreeSet.

考虑球员(Player)类,包括以下信息:姓名,金牌数,银牌数,铜牌数。

球员(Player)可以相互根据原理进行比较:

谁拥有更多的金牌则排名会更高

如果两个人有相同数量的金牌,谁拥有更多的银牌则排名就越靠前

如果两个人有相同数量的金牌和银牌,谁拥有更多铜牌则排名将更高

其他的则被视为是同等级的

Player类将实现 java.lang.Comparable 的接口

Player.java

package com.yiibai.tutorial.javacollection.sortedset;

public class Player implements Comparable {

    private String name;

    private int goldMedal;

    private int silverMedal;

    private int bronzeMedal;

    public Player(String name, int goldMedal, int silverMedal, int bronzeMedal) {

        this.name = name;

        this.goldMedal = goldMedal;

        this.silverMedal = silverMedal;

        this.bronzeMedal = bronzeMedal;

    }


    // Compare this player with other player

    // Return < 0 means this player < other

    // Return > 0 means this player > other

    // Return 0 means this player = other

    @Override

    public int compareTo(Player other) {

        // Compare the number of gold medals.

        int value = this.goldMedal - other.goldMedal;

        if (value != 0) {

            return value;

        }


        // Compare the number of silver medals.

        value = this.silverMedal - other.silverMedal;

        if (value != 0) {

            return value;

        }


        // Compare the number of bronze medals.

        value = this.bronzeMedal - other.bronzeMedal;

        return value;

    }

    @Override

    public String toString() {

        return "[" + this.name + ", Gold: " + this.goldMedal + ", Silver: " + this.silverMedal + ", Bronze: "

                + this.bronzeMedal + "]";

    }

}

SortedSetDemo.java

package com.yiibai.tutorial.javacollection.sortedset;

import java.util.SortedSet;

import java.util.TreeSet;

public class SortedSetDemo {

    public static void main(String[] args) {


        // Create SortedSet object.

        SortedSet players = new TreeSet();

        Player tom = new Player("Tom", 1, 3, 5);

        Player jerry = new Player("Jerry", 3, 1, 3);

        Player donald = new Player("Donal", 2, 10, 0);



        // Add element to set

        // They will automatically be sorted (Ascending).

        players.add(tom);

        players.add(jerry);

        players.add(donald);



        // Print out elements

        for(Player player : players) {

            System.out.println("Player: "+ player);

        }

    }

}

运行 SortedSetDemo 实例的结果如下:

Player: [Tom, Gold: 1, Silver: 3, Bronze: 5]

Player: [Donal, Gold: 2, Silver: 10, Bronze: 0]

Player: [Jerry, Gold: 3, Silver: 1, Bronze: 3]

6- Map组

6.1- 映射组接口

由 java.util.Map 接口主导 Map 组。该接口有2个子接口分别是java.util.SortedMap和java.util.concurrent.ConcurrentMap。 ConcurrentMap不属于java.util包,它是从Java版本1.5引入的,我们不打算在教程讲解它。 Map组特点是存储键/值对的数据。

6.2- 在Map组中的类

6.3- java.util.Map接口

SN方法及描述

1void clear( )

调用移除Map中的所有键/值对(可选操作)

2boolean containsKey(Object k)

如果调用映射包含一个键k,则返回true,否则返回false

3boolean containsValue(Object v)

如果Map包含一个值v,则返回true。否则,返回false

4Set> entrySet( )

返回包含在映射中条目的集合。集合中包含 Map.Entry 类型的对象。这种方法提供调用映射设置视图

5boolean equals(Object obj)

如果 obj 是一个在 Map 中包含的相同项目,则返回true。否则,返回false

6Object get(K k)

返回与k关联的值

7int hashCode( )

返回调用映射的哈希码

8boolean isEmpty( )

返回true如果调用映射为空。否则,返回false

9Set keySet( )

返回包含调用Map中的键的集合(Set),该方法提供了在调用映射中的键的一组视图

10Object put(K k, V v)

放入调用映射一个条目,覆盖先前与键相关联的值。键和值分别为K和V。如果该键不存在,则返回null。否则关联到键先前的值被返回(可选操作)

11void putAll(Map m)

把 m 中的全部项目放入此Map(可选操作)

12Object remove(Object k)

删除其键等于k处的项(可选操作)

13int size( )

返回映射的键/值对的数量

14Collection values( )

返回包含映射中值的集合,该方法提供了在映射中的值的集合视图。

可选方法(可选操作),可以被支持它的实现类或没有,如果不支持,它会抛出 UnsupportedOperationException 异常:

import java.util.Collection;

import java.util.Map;

import java.util.Set;

public class MyMap implements Map{

  .....

    // If you call this method, an exception will be thrown (unconditional).

    @Override

    public void clear() {

        throw new java.lang.UnsupportedOperationException();       

    } 

因此,MyMap类不支持clear()方法的真正含意。如果用户有意使用 MyMap 中的这个方法,会收到一个异常。

MapDemo.java

package com.yiibai.tutorial.javacollection.map;

import java.util.HashMap;

import java.util.Map;

import java.util.Set;

public class MapDemo {


    public static void main(String[] args) {

        Map map = new HashMap();

        map.put("01000005", "Tom");

        map.put("01000002", "Jerry");

        map.put("01000003", "Tom");

        map.put("01000004", "Donald");



        // Get a set view of the keys contained in this map

        // This collection is not sorted

        Set phones = map.keySet();

        for (String phone : phones) {

            System.out.println("Phone: " + phone + " : " + map.get(phone));

        }

    }

}

运行实例的结果如下:

Phone: 01000004 : Donald

Phone: 01000003 : Tom

Phone: 01000005 : Tom

Phone: 01000002 : Jerry

您可以通过Map.Entry访问映射的数据,见下图:

MapEntryDemo.java

package com.yiibai.tutorial.javacollection.map;

import java.util.HashMap;

import java.util.Map;

import java.util.Set;

import java.util.Map.Entry;

public class MapEntryDemo {

    public static void main(String[] args) {

        Map map = new HashMap();

        map.put("01000005", "Tom");

        map.put("01000002", "Jerry");

        map.put("01000003", "Tom");

        map.put("01000004", "Donald");


        // Get set of entries

        // This entry may not sort by key.

        Set> entries = map.entrySet();

        for (Entry entry : entries) {

            System.out.println("Phone: " + entry.getKey() + " : " + entry.getValue());

        }

    }

}

运行实例的结果如下:

Phone: 01000004 : Donald

Phone: 01000003 : Tom

Phone: 01000005 : Tom

Phone: 01000002 : Jerry

6.4- java.util.SortedMap接口

SortedMap是 Map 的子接口。它确保键/值对根据键以升序排列。

在java.util中只有一个类实现 SortedMap 接口,它就是TreeMap。

SortedMap 类的方法:

SN描述及方法

1Comparator comparator( )

返回调用Map的比较器(comparator),如果自然顺序用于调用映射,则返回null

2Object firstKey( )

返回调用映射的第一个键

3SortedMap headMap(Object end)

返回映射条目与小于 end 键的有序映射

4Object lastKey( )

返回调用映射的最后一个键

5SortedMap subMap(Object start, Object end)

返回一个包含键大于或等于start 并小于 end 的那些条目的映射

6SortedMap tailMap(Object start)

返回包含键大于或等于 start 的那些条目的映射.

SortedMapDemo.java

package com.yiibai.tutorial.javacollection.sortedmap;

import java.util.Map;

import java.util.Set;

import java.util.TreeMap;

public class SortedMapDemo {

    public static void main(String[] args) {

        Map map = new TreeMap();

        map.put("01000005", "Tom");

        map.put("01000002", "Jerry");

        map.put("01000003", "Tom");

        map.put("01000004", "Donald");


        // This set has been sorted in ascending

        Set keys = map.keySet();

        for (String key : keys) {

            System.out.println("Phone: " + key);

        }


        System.out.println("-----");


        // This set has been sorted in ascending

        Set> entries = map.entrySet();

        for (Map.Entry entry : entries) {

            System.out.println("Phone: " + entry.getKey());

        }

    }

}

运行实例的结果如下:

Phone: 01000002

Phone: 01000003

Phone: 01000004

Phone: 01000005

-----

Phone: 01000002

Phone: 01000003

Phone: 01000004

Phone: 01000005

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,497评论 18 139
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,497评论 18 399
  • Scala的集合类可以从三个维度进行切分: 可变与不可变集合(Immutable and mutable coll...
    时待吾阅读 5,773评论 0 4
  • D27 阿尔法号阿基米德舱 110-黄丹 破执着信念 1.不再执着于寻求具象的结果,而是探讨各种可能性和更适合的方...
    Michelle沐晨阅读 168评论 0 0
  • (二) 2016.09.10 星期六 多云 今天是我开学的可喜...
    葉舒阅读 233评论 0 0