zoukankan      html  css  js  c++  java
  • Java编程手冊-Collection框架(下)

    建议先看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)
    5.1  HashSet<E>的样例
    以下写了一个Book类而且写了一个Book的集合。
    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的交集。


    须要注意的是Set中元素的排序是随意的,并非插入的顺序。

    5.2  LinkedHashSet<E>的样例
    不像HashSet。LinkedHashSet<E>构建的是一个基于哈希表的链表,主要是为了更好的插入和删除效率。另外,它里面元素的顺序维持的就是插入的顺序(比如:add()方法)。

    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()加入的顺序是一致的。

    5.3  NavigableSet<E> & SortedSet<E>接口
    SortedSet<E>在元素add()的过程中会进行排序。排序策略使用的是Comparable的实现或者提供的Comparator对象。


    NavigableSet<E>是Set的子接口,它提供了一些额外的方法。
    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>的实现.
    样例——实现Comparable的TreeSet

    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实现的方法。


    样例——实现ComparatorTreeSet
    以下我们来又一次上面的样例,这次使用的是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()方法来是集合倒序。

    6.  Queue<E>接口与实现
    Queue中的元素是以一种特定的顺序进行加入和删除。比如典型的先入先出。deque是一个双向队列。它的元素的加入和删除能够在两端进行。

    Collection<E>操作之外,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>接口,它是双向链表结构。

    7.  Map<K,V>接口与实现
    Map集合相应的是一个键值对。每一个key相应一个value,键值不同意反复,value是同意反复的。它跟线性数组有些同样,不同的是它使用key来进行索引訪问相应的value,所以map使用使用随意的key。

     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. 算法
    Collection框架提供了两个工具类:java.util.Arrays 和 java.util.Collections,它们提供了一些主要的算法。比如插入和查找等等。
    另外须要注意的是Collections是工具类,Collection是集合框架的接口。

    8.1  java.util.Arrays工具类
    java.util.Arrays包括了非常多的静态方法来对数组进行排序或者查找等等操作。


    Array是Java中的引用类型,它能够包括基本数据类型,也能够包括对象数据类型。Java中的数组能够包括9种数据类型,byteshortintlongfloatdoublecharboolean和对象类型。


    Sorting - Arrays.sort()
    对除boolean类型之外的基本数据类型以及对象类型的数据进行排序。比如int[]数组:
    // 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的超类。

    Searching - Arrays.binarySearch()
    同理。也有对于全部基本数据类型或者对象类型查找的方法。在运行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)


    Filling - Arrays.fill()
    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[]

    转换为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上面。不能使用在SetQueue 和 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的实现类都不是同步的,比如ArrayListHashSet 和  HashMap ,也就是它们不是线程安全的,除了Vector 和 HashTable是同步的,假设我们不想使用Vector 和 HashTable,我们能够通过静态的 Collections.synchronizedXxx() 创建同步的CollectionListSetSortedSetMap 和 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 Programming Tutorial The Collection Framework

  • 相关阅读:
    回文自动机+DFS
    iOS 图表工具charts之CandleStickChartView(K线)
    iOS 图表工具charts之PieChartView
    iOS 图表工具charts之BarChartView
    iOS 图表工具charts之LineChartView
    iOS 图表工具charts介绍
    cocoapods [!] Unable to find a pod with name, author, summary, or description matching `xx`
    iOS charts CombinedChartView First and last bars are shown half only
    iOS OC中桥接swift第三方库
    iOS 日志系统 本地日志打包上传到服务器
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/7189833.html
Copyright © 2011-2022 走看看