Java编程手冊-Collection框架(下)
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
Set<E>接口的实现类包含:
- HashSet<E>:在一个哈希表中存储元素(哈希值通过hashcode()产生),HashSet是Set的全面实现。
- LinkedHashSet<E>:存储元素在一个哈希链表中,因此它有更高的插入删除效率。
- TreeSet<E>: 它也实现了子接口NavigableSet 和 SortedSet,存储元素在一个红黑树的数据结构中,它的搜索、加入、删除效率非常高,时间复杂度为O(log(n)
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;
   }
}
我们须要提供equals()方法。这样实现Set的集合能够验证元素的相等性和反复性,比如,我们选用id来区分不同的对象元素。这样我们实现的equals()方法就是假设两个对象的id同样。那么就返回true。另外。我们也须要又一次hashCode()方法来保持它也equals()的一致性。
关于equals()和hashCode()的关联能够參考文章:Effective
 Java——对全部对象通用的方法
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]
}
}
能够看到,Set的输出的顺序跟add()加入的顺序是一致的。
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实现的方法。
以下我们来又一次上面的样例,这次使用的是Comparator对象来实现对象的比較。
public class PhoneBookEntry {
   public String name, address, phone;
   public PhoneBookEntry(String name) {
      this.name = name;
   }
   @Override
   public String toString() {
      return name;
   }
}
上面的PhoneBookEntry并没有实现Comparator,我们这里是单独定义一个Comparator实例,使用这个实例来创建TreeSet。
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
Deque<E>也提供了额外的方法来操作队列的两端
// 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));
}
样例——HashMap
// 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);
}
}
8. 算法
java.util.Arrays 和 java.util.Collections,它们提供了一些主要的算法。比如插入和查找等等。java.util.Arrays工具类
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[]外)
 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)
Equality Comparison - Arrays.equals()
public static boolean equals(int[] a1, int[] a2)
// Similar methods for byte[], short[], long[], float[], double[], char[], boolean[] and Object[]
Copying - Arrays.copyOf() 和 Arrays.copyOfRange()
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[]
转换为List - Arrays.asList()
// 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)
8.2  java.util.Collections工具类
跟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)能够自己主动排序。
Searching - Collections.binarySearch()
在使用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)
Synchronized Collection, List, Set & Map
非常多的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();
......
}
Java编程手冊-Collection框架(下)的更多相关文章
- Java编程手冊-Collection框架(上)
		该文章所讲内容基本涵盖了Collection里面的全部东西,尽管基于jdk 1.5的.可是思路非常清晰 1.引言 1.1 Collection框架的介绍 尽管我们能够使用数组去存储具有同样类型的元素集 ... 
- 阿里Java开发手冊之编程规约
		对于程序猿来说,编程规范能够养成良好的编程习惯,提高代码质量,减少沟通成本.就在2月9号,阿里出了一份Java开发手冊(正式版),分为编程规约.异常日志.MySQL规约,project规约.安全规约五 ... 
- Spring 08: AOP面向切面编程 + 手写AOP框架
		核心解读 AOP:Aspect Oriented Programming,面向切面编程 核心1:将公共的,通用的,重复的代码单独开发,在需要时反织回去 核心2:面向接口编程,即设置接口类型的变量,传入 ... 
- Java编程的逻辑 (90) - 正则表达式 (下 -  剖析常见表达式)
		本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http:/ ... 
- Java编程的逻辑 (25) - 异常 (下)
		本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ... 
- Java编程的逻辑 (37) - 泛型 (下) - 细节和局限性
		本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http:/ ... 
- Java集合源码 -- Collection框架概述
		1.概述 collection框架是用于处理各种数据结构的,要根据各种数据结构的特点理解它 它能够保存对象,并提供很多的操作去管理对象,当你面临下面的情况时,也许你应该考虑用集合类 1.容器的长度是不 ... 
- Java开发手冊 Java学习手冊教程(MtJava开发手冊)
		本文档的版权归MtJava文档小组全部,本文档及其描写叙述的内容受有关法律的版权保护,对本文档内容的不论什么形式的非法复制.泄露或散布.将导致对应的法律责任. MtJava仅仅是一个学习Java的简化 ... 
- java项目(非ssm等框架)下的quartz定时器任务
		第一步:引包 要使用Quartz,必须要引入以下这几个包: 1.log4j-1.2.16 2.quartz-2.1.7 3.slf4j-api-1.6.1.jar 4.slf4j-log4j12-1. ... 
随机推荐
- 《Unix环境高级编程》读书笔记 第4章-文件和目录
			1. stat结构的基本形式: on error 24. 设备特殊文件 每个文件系统所在的存储设备都由其主.次设备号表示. 设备号所用的数据类型是基本系统数据类型dev_t. 主设备号标识设备驱动程序 ... 
- P2421 [NOI2002]荒岛野人 扩展欧几里得 枚举
			Code: #include<cstdio> #include<cstring> #include<algorithm> using namespace std; ... 
- HTTP——学习笔记(8)
			HTTP中的一些协议内容会限制某些网站的功能使用 比如,Facebook这类的社交网站,需要实时地观察到海量用户公开发布的内容,而HTTP中的以下标准就会成为瓶颈: 一条连接上只可发送一个请求 请求只 ... 
- javascript取前n天的日期两种方法
			方法一: var d = new Date(); d = new Date(d.getFullYear(),d.getMonth(),d.getDate()-n); 方法二: var now = ne ... 
- a+=b 等价于 a=a+b ?
			a += b和a = a + b全然等价么(java)?可能非常多人以为是一样的,事实上并不是等价的,以下看一下证据吧. public class Test { public static void ... 
- 2、Python列表和元组
			2.Python序列 序列是一种数据存储方式,类似于C语言的数组.简单的说序列是一块用来存储多个值的连续内存空间,同一个序列的元素通常是相关的. Python中常用的序列结构有列表.元组.字典.字符串 ... 
- WinRar 设置默认的压缩格式为zip
			By default, WinRar uses the RAR archive format for compressing files. You may prefer using the more ... 
- BZOJ 3524主席树裸题 (雾)
			思路: 按权值建一棵主席树 (但是这好像不是正解 空间复杂度是不对的--.) //By SiriusRen #include <cstdio> #include <cstring&g ... 
- Android项目实战(五十七):Glide 高斯模糊效果
			核心需要高斯模糊的库 compile 'jp.wasabeef:glide-transformations:2.0.1' 针对于3.7的版本 使用方法为: //加载背景, Glide.with(Mus ... 
- 《剑指offer》反转链表
			一.题目描述 输入一个链表,反转链表后,输出链表的所有元素. 二.输入描述 输入一个链表 三.输出描述 返回逆转后的链表 四.牛客网提供的框架 /* struct ListNode { int val ... 
