5. Set
Set

Set
boolean add(E o) // add the specified element if it is not already present boolean remove(Object o) // remove the specified element if it is present boolean contains(Object o) // return true if it contains o // Set operations boolean addAll(Collection c) // Set union boolean retainAll(Collection c) // Set intersection
HashSet
public class Book {
private int id;
private String title;
// Constructor
public Book(int id, String title) {
this.id = id;
this.title = title;
}
@Override
public String toString() {
return id + ": " + title;
}
// Two book are equal if they have the same id
@Override
public boolean equals(Object o) {
if (!(o instanceof Book)) {
return false;
}
return this.id == ((Book)o).id;
}
// Consistent with equals(). Two objects which are equal have the same hash code.
@Override
public int hashCode() {
return id;
}
}
import java.util.HashSet;
import java.util.Set;
public class TestHashSet {
public static void main(String[] args) {
Book book1 = new Book(1, "Java for Dummies");
Book book1Dup = new Book(1, "Java for the Dummies"); // same id as above
Book book2 = new Book(2, "Java for more Dummies");
Book book3 = new Book(3, "more Java for more Dummies");
Set set1 = new HashSet();
set1.add(book1);
set1.add(book1Dup); // duplicate id, not added
set1.add(book1); // added twice, not added
set1.add(book3);
set1.add(null); // Set can contain a null
set1.add(null); // but no duplicate
set1.add(book2);
System.out.println(set1); // [null, 1: Java for Dummies,
// 2: Java for more Dummies, 3: more Java for more Dummies]
set1.remove(book1);
set1.remove(book3);
System.out.println(set1); // [null, 2: Java for more Dummies]
Set set2 = new HashSet();
set2.add(book3);
System.out.println(set2); // [3: more Java for more Dummies]
set2.addAll(set1); // "union" with set1
System.out.println(set2); // [null, 2: Java for more Dummies, 3: more Java for more Dummies]
set2.remove(null);
System.out.println(set2); // [2: Java for more Dummies, 3: more Java for more Dummies]
set2.retainAll(set1); // "intersection" with set1
System.out.println(set2); // [2: Java for more Dummies]
}
}
一個Set不能存放重復的元素,檢查元素的重復性就是通過重寫的equal()方法來檢查的。另外一個Set中只能存放一個null元素。addAll()是否是將兩個Set聯合,retainAll()是取兩個Set的交集。
需要注意的是Set中元素的排序是任意的,並不是插入的順序。
5.2 LinkedHashSet
import java.util.LinkedHashSet;
import java.util.Set;
public class TestLinkedHashSet {
public static void main(String[] args) {
Book book1 = new Book(1, "Java for Dummies");
Book book1Dup = new Book(1, "Java for the Dummies"); // same id as above
Book book2 = new Book(2, "Java for more Dummies");
Book book3 = new Book(3, "more Java for more Dummies");
Set set = new LinkedHashSet();
set.add(book1);
set.add(book1Dup); // duplicate id, not added
set.add(book1); // added twice, not added
set.add(book3);
set.add(null); // Set can contain a null
set.add(null); // but no duplicate
set.add(book2);
System.out.println(set); // [1: Java for Dummies, 3: more Java for more Dummies,
// null, 2: Java for more Dummies]
}
}
Iterator5.4 TreeSetdescendingIterator() // Returns an iterator over the elements in this set, // in descending order. Iterator iterator() // Returns an iterator over the elements in this set, in ascending order. // Per-element operation E floor(E e) // Returns the greatest element in this set less than or equal to the given element, // or null if there is no such element. E ceiling(E e) // Returns the least element in this set greater than or equal to the given element, // or null if there is no such element. E lower(E e) // Returns the greatest element in this set strictly less than the given element, // or null if there is no such element. E higher(E e) // Returns the least element in this set strictly greater than the given element, // or null if there is no such element. // Subset operation SortedSet headSet(E toElement) // Returns a view of the portion of this set // whose elements are strictly less than toElement. SortedSet tailSet(E fromElement) // Returns a view of the portion of this set // whose elements are greater than or equal to fromElement. SortedSet subSet(E fromElement, E toElement) // Returns a view of the portion of this set // whose elements range from fromElement, inclusive, to toElement, exclusive.
TreeSet是NavigableSet 和SortedSet的實現 .
例子——實現Comparable的TreeSet
public class AddressBookEntry implements Comparable {
private String name, address, phone;
public AddressBookEntry(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
@Override
public int compareTo(AddressBookEntry another) {
return this.name.compareToIgnoreCase(another.name);
}
@Override
public boolean equals(Object o) {
if (!(o instanceof AddressBookEntry)) {
return false;
}
return this.name.equalsIgnoreCase(((AddressBookEntry)o).name);
}
@Override
public int hashCode() {
return name.length();
}
}
AddressBookEntry實現了Comparable接口,為了在TreeSet中進行使用,它重寫了compareTo()方法去比較name,它同時也重新了equals()和hashCode()方法,主要為了保持跟compareTo()的一致性。
import java.util.TreeSet;
public class TestTreeSetComparable {
public static void main(String[] args) {
AddressBookEntry addr1 = new AddressBookEntry("peter");
AddressBookEntry addr2 = new AddressBookEntry("PAUL");
AddressBookEntry addr3 = new AddressBookEntry("Patrick");
TreeSet set = new TreeSet();
set.add(addr1);
set.add(addr2);
set.add(addr3);
System.out.println(set); // [Patrick, PAUL, peter]
System.out.println(set.floor(addr2)); // PAUL
System.out.println(set.lower(addr2)); // Patrick
System.out.println(set.headSet(addr2)); // [Patrick]
System.out.println(set.tailSet(addr2)); // [PAUL, peter]
}
}
可以看到AddressBookEntry對象在add()操作過程中進行了排序,使用的就是Comparable實現的方法。
例子——實現Comparator的TreeSet
public class PhoneBookEntry {
public String name, address, phone;
public PhoneBookEntry(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
import java.util.Set;
import java.util.TreeSet;
import java.util.Comparator;
public class TestTreeSetComparator {
public static class PhoneBookComparator implements Comparator {
@Override
public int compare(PhoneBookEntry p1, PhoneBookEntry p2) {
return p2.name.compareToIgnoreCase(p1.name); // descending name
}
}
public static void main(String[] args) {
PhoneBookEntry addr1 = new PhoneBookEntry("peter");
PhoneBookEntry addr2 = new PhoneBookEntry("PAUL");
PhoneBookEntry addr3 = new PhoneBookEntry("Patrick");
Comparator comp = new PhoneBookComparator();
TreeSet set = new TreeSet(comp);
set.add(addr1);
set.add(addr2);
set.add(addr3);
System.out.println(set); // [peter, PAUL, Patrick]
Set newSet = set.descendingSet(); // Reverse the order
System.out.println(newSet); // [Patrick, PAUL, peter]
}
}
上面我們創建了一個帶有BookComparator實例的TreeSet,這樣上面Set中對象的比較使用的就是BookComparator的compare方法,在上面例子中,調用TreeSet的descendingSet()方法來是集合倒序。
6. Queue
在CollectionQueue也額外添加了插入、獲取、查看的操作方法,每個方法都提供了兩種形式:一個是如果操作失敗會拋出異常,另外一個如果操作是否會返回一個值(false或者null,據具體操作而定)。// Insertion at the end of the queue boolean add(E e) // throws IllegalStateException if no space is currently available boolean offer(E e) // returns true if the element was added to this queue, else false // Extract element at the head of the queue E remove() // throws NoSuchElementException if this queue is empty E poll() // returns the head of this queue, or null if this queue is empty // Inspection (retrieve the element at the head, but does not remove) E element() // throws NoSuchElementException if this queue is empty E peek() // returns the head of this queue, or null if this queue is empty
// Insertion void addFirst(E e) void addLast(E e) boolean offerFirst(E e) boolean offerLast(E e) // Retrieve and Remove E removeFirst() E removeLast() E pollFirst() E pollLast() // Retrieve but does not remove E getFirst() E getLast() E peekFirst() E peekLast()一個Deque可以看做是一個FIFO對象(通過
add(e),remove(),element(),offer(e),poll(),peek()方法),也可以看做是一個LIFO隊列(通過push(e),pop(),peek()方法)。
Queue和Deque的實現類如下:
PriorityQueue: 這個隊列可以使用一個指定的順序去進行排序,而不是FIFO的順序。ArrayDeque: 使用queue或者deque來實現的動態數組,類似於ArrayListLinkedList: 它在實現ListQueue和Deque接口,它是雙向鏈表結構。
Map接口聲明了下面抽象方法。
V get(Object key) // Returns the value of the specified key V put(K key, V value) // Associate the specified value with the specified key boolean containsKey(Object key) // Is this map has specified key? boolean containsValue(Object value) // Views SetkeySet() // Returns a set view of the keys Collection values() // Returns a collection view of the values Set entrySet() // Returns a set view of the key-value
Map接口的實現類包括:
HashMap:HashMap實現了MapTreeMap:實現了SortedMapLinkedHashMap:帶有鏈表的哈希表,方便插入和刪除Hashtable:它是對MapHashMap例子——HashMapaMap = new HashMap (); aMap.put("1", "Monday"); aMap.put("2", "Tuesday"); aMap.put("3", "Wednesday"); String str1 = aMap.get("1"); // No need downcast System.out.println(str1); String str2 = aMap.get("2"); System.out.println(str2); String str3 = aMap.get("3"); System.out.println(str3); Set keys = aMap.keySet(); for (String str : keys) { System.out.print(str); System.out.print(":"); System.out.println(aMap.get(str)); }
// Counts the frequency of each of the words in a file given in the command-line,
// and saves in a map of {word, freq}.
import java.util.Map;
import java.util.HashMap;
import java.util.Scanner;
import java.io.File;
public class WordCount {
public static void main(String[] args) throws Exception {
Scanner in = new Scanner(new File(args[0]));
Map map = new HashMap();
while (in.hasNext()) {
String word = in.next();
int freq = (map.get(word) == null) ? 1 : map.get(word) + 1; // type-safe
map.put(word, freq); // autobox int to Integer and upcast, type-check
}
System.out.println(map);
}
}
java.util.Arrays和java.util.Collections,它們提供了一些基本的算法,例如插入和查找等等。
另外需要注意的是Collections是工具類,Collection是集合框架的接口。
8.1 java.util.Arrays工具類
java.util.Arrays包含了很多的靜態方法來對數組進行排序或者查找等等操作。
Array是Java中的引用類型,它可以包含基本數據類型,也可以包含對象數據類型,Java中的數組可以包含9種數據類型,byte,short,int,long,float,double,char,boolean和對象類型。
Sorting - Arrays.sort()// Sort the given array into ascending order public static void sort(int[] a) // Sort between fromIndex (inclusive) and toTodex (exclusive) public static void sort(int[] a, int fromIndex, int toIndex)同理,sort()可用於
byte[],short[],long[],float[],double[],char[](除boolean[]外) andObject[]中。對應Object[],對象必須實現Comparable接口的compareTo()方法。
public static void sort(Object[] a) public static void sort(Object[] a, int fromIndex, int toIndex)對於泛型對象的排序,通過提供Comparator對象來實現排序。
public static假設你想對一個Integer數組進行排序,也就是T為Integer,你可以實現一個Comparatorvoid sort(T[] a, Comparator c) public static void sort(T[] a, int fromIndex, int toIndex, Comparator c)
binarySearch()執行對數組需要進行排序。
public static int binarySearch(int[] a, int key) public static int binarySearch(int[] a, int fromIndex, int toIndex, int key) // Similar methods for byte[], short[], long[], float[], double[] and char[] // Searching objects, which implements Comparable public static int binarySearch(Object[] a, Object key) public static int binarySearch(Object[] a, int fromIndex, int toIndex, Object key) // Searching generic objects, based on the given Comparator public staticint binarySearch(T[] a, T key, Comparator c) public static int binarySearch(T[] a, T key, int fromIndex, int toIndex, Comparator c)
public static boolean equals(int[] a1, int[] a2) // Similar methods for byte[], short[], long[], float[], double[], char[], boolean[] and Object[]
public static int[] copyOf(int[] original, int newLength) // Copies the given array, truncating or padding with zeros (if necessary) so the copy has the specified length public static int[] copyOfRange(int[] original, int from, int to) // padded with 0 if to is beyond the length // Similar methods for byte[], short[], long[], float[], double[], char[] and boolean[] public staticFilling - Arrays.fill()T[] copyOf(T[] original, int newLength) public static T[] copyOfRange(T[] original, int from, int to) public static T[] copyOf(U[] original, int newLength, Class newType) public static T[] copyOfRange(U[] original, int from, int to, Class newType)
public static void fill(int[] a, int value) public static void fill(int[] a, int fromIndex, int toIndex, int value) // Similar methods for byte[], short[], long[], float[], double[], char[] and boolean[] and Object[]Description - Arrays.toString()
// Returns a string representation of the contents of the specified array. public static String toString(int[] a) // Similar methods for byte[], short[], long[], float[], double[], char[] and boolean[] and Object[]
// Returns a fixed-size list backed by the specified array. // Change to the list write-thru to the array. public static8.2 java.util.Collections工具類List asList(T[] a)
跟java.util.Arrays一樣,java.util.Collections也提供了靜態的方法來對集合進行操作。、
Sorting - Collections.sort()
// Sorts the specified list into ascending order. The objects shall implement Comparable. public static需要注意的是Collections.sort()只能用在List上面,不能使用在> void sort(List list) // Sorts the specified list according to the order induced by the specified comparator. public static void sort(List list, Comparator c)
Set,Queue和Map上,SortedSet(TreeSet) 和SortedMap(TreeMap)可以自動排序。在使用binarySearch()之前,List必須進行排序。
public staticint binarySearch(List> list, T key) public static int binarySearch(List list, T key, Comparator c)
最大和最小 - Collections.max() & Collections.min()
// Returns the maximum/minimum element of the given collection, according to the natural ordering of its elements. public static> T max(Collection c) public static > T min(Collection c) // Returns the maximum/minimum element of the given collection, according to the order induced by the specified comparator. public static T max(Collection c, Comparator comp) public static T min(Collection c, Comparator comp)
很多的Collection的實現類都不是同步的,例如ArrayList,HashSet和HashMap,也就是它們不是線程安全的,除了Vector和HashTable是同步的,如果我們不想使用Vector和HashTable,我們可以通過靜態的Collections.synchronizedXxx()創建同步的Collection,List,Set,SortedSet,Map和SortedMap。
// Returns a synchronized (thread-safe) collection backed by the specified collection. public static對於上面方法返回的對象,在遍歷的時候,必須包含在synchronize塊中。Collection synchronizedCollection(Collection c) // Others public static List synchronizedList(List list) public static Set synchronizedSet(Set set) public static SortedSet synchronizedSortedSet(SortedSet set) public static Map synchronizedMap(Map map) public static SortedMap synchronizedSortedMap(SortedMap map)
List lst = Collections.synchronizedList(new ArrayList());
......
synchronized(lst) { // must be enclosed in a synchronized block
Iterator iter = lst.iterator();
while (iter.hasNext())
iter.next();
......
}