标签:
5. Set<E>接口与实现
Set<E>接口表示一个数学的集合,它不允许元素的重复,只能包含一个null元素。
Set<E>接口声明了下面抽象方法。
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<? extends E> c) // Set union boolean retainAll(Collection<?> c) // Set intersection
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<Book> set1 = new HashSet<Book>(); 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<Book> set2 = new HashSet<Book>(); 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的交集。
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<Book> set = new LinkedHashSet<Book>(); 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] } }
Iterator<E> descendingIterator() // Returns an iterator over the elements in this set, // in descending order. Iterator<E> 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<E> headSet(E toElement) // Returns a view of the portion of this set // whose elements are strictly less than toElement. SortedSet<E> tailSet(E fromElement) // Returns a view of the portion of this set // whose elements are greater than or equal to fromElement. SortedSet<E> subSet(E fromElement, E toElement) // Returns a view of the portion of this set // whose elements range from fromElement, inclusive, to toElement, exclusive.5.4 TreeSet<E>例子
TreeSet<E>是NavigableSet<E>
和 SortedSet<E>的实现
.public class AddressBookEntry implements Comparable<AddressBookEntry> { 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<AddressBookEntry> set = new TreeSet<AddressBookEntry>(); 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实现的方法。
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<PhoneBookEntry> { @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<PhoneBookEntry> comp = new PhoneBookComparator(); TreeSet<PhoneBookEntry> set = new TreeSet<PhoneBookEntry>(comp); set.add(addr1); set.add(addr2); set.add(addr3); System.out.println(set); // [peter, PAUL, Patrick] Set<PhoneBookEntry> newSet = set.descendingSet(); // Reverse the order System.out.println(newSet); // [Patrick, PAUL, peter] } }上面我们创建了一个带有BookComparator实例的TreeSet,这样上面Set中对象的比较使用的就是BookComparator的compare方法,在上面例子中,调用TreeSet的descendingSet()方法来是集合倒序。
Queue<E>
也额外添加了插入、获取、查看的操作方法,每个方法都提供了两种形式:一个是如果操作失败会抛出异常,另外一个如果操作是否会返回一个值(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<E>
和 Deque<E>的实现类如下:
PriorityQueue<E>
:
这个队列可以使用一个指定的顺序去进行排序,而不是FIFO的顺序。ArrayDeque<E>
:
使用queue或者deque来实现的动态数组,类似于ArrayList<E>。LinkedList<E>
:
它在实现List<E>接口的基础上,也实现了Queue<E>
和 Deque<E>接口,它是双向链表结构。
Map<K,V>接口声明了下面抽象方法。
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 Set<K> keySet() // Returns a set view of the keys Collection<V> values() // Returns a collection view of the values Set entrySet() // Returns a set view of the key-value
Map<K,V>接口的实现类包括:
HashMap<K,V>
:HashMap实现了Map<K,V>,并且是Map全面的实现,但是HashMap的方法不是同步的,也就是线程不安全。TreeMap<K,V>
:实现了SortedMap<K,V>接口的红黑树。LinkedHashMap<K,V>
:带有链表的哈希表,方便插入和删除Hashtable<K,V>
:它是对Map<K,V>方法的同步实现,也就是它是线程安全的,另外它不允许key和value为null。HashMap<String, String> aMap = new HashMap<String, String>(); 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<String> 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<String, Integer> map = new HashMap<String, Integer>(); 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,它们提供了一些基本的算法,例如插入和查找等等。
byte
, short
, int
, long
, float
, double
, char
, boolean和对象类型。
// 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[]外
)
and Object[]
中。对应Object[],对象必须实现Comparable接口的compareTo()方法。
public static void sort(Object[] a) public static void sort(Object[] a, int fromIndex, int toIndex)对于泛型对象的排序,通过提供Comparator对象来实现排序。
public static <T> void sort(T[] a, Comparator<? super T> c) public static <T> void sort(T[] a, int fromIndex, int toIndex, Comparator<? super T> c)假设你想对一个Integer数组进行排序,也就是T为Integer,你可以实现一个Comparator<Integer>或者Comparator<Number>或者Comparator<Object>实例来提供给sort方法,
Object
and Number都是Integer的超类。
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 static <T> int binarySearch(T[] a, T key, Comparator<? super T> c) public static <T> int binarySearch(T[] a, T key, int fromIndex, int toIndex, Comparator<? super T> 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 static <T> T[] copyOf(T[] original, int newLength) public static <T> T[] copyOfRange(T[] original, int from, int to) public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) public static <T,U> T[] copyOfRange(U[] original, int from, int to, Class<? extends T[]> 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[]
// 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 static <T> List<T> 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 <T extends Comparable<? super T>> void sort(List<T> list) // Sorts the specified list according to the order induced by the specified comparator. public static <T> void sort(List<T> list, Comparator<? super T> c)需要注意的是Collections.sort()只能用在List上面,不能使用在
Set
, Queue
和 Map上,SortedSet
(TreeSet
)
和 SortedMap
(TreeMap)可以自动排序。
在使用binarySearch()之前,List必须进行排序。
public static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key) public static <T> int binarySearch(List<? extends T> list, T key, Comparator<? super T> 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 extends Object & Comparable<? super T>> T max(Collection<? extends T> c) public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> c) // Returns the maximum/minimum element of the given collection, according to the order induced by the specified comparator. public static <T> T max(Collection<? extends T> c, Comparator<? super T> comp) public static <T> T min(Collection<? extends T> c, Comparator<? super T> 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 <T> Collection<T> synchronizedCollection(Collection<T> c) // Others public static <T> List<T> synchronizedList(List<T> list) public static <T> Set<T> synchronizedSet(Set<T> set) public static <T> SortedSet<T> synchronizedSortedSet(SortedSet<T> set) public static <K,V> Map<K,V> synchronizedMap(Map<K,V> map) public static <K,V> SortedMap<K,V> synchronizedSortedMap(SortedMap<K,V> map)对于上面方法返回的对象,在遍历的时候,必须包含在synchronize块中。
List lst = Collections.synchronizedList(new ArrayList()); ...... synchronized(lst) { // must be enclosed in a synchronized block Iterator iter = lst.iterator(); while (iter.hasNext()) iter.next(); ...... }
标签:
原文地址:http://blog.csdn.net/hp910315/article/details/51018135