今天開始閱讀jdk1.8的集合部分,平時在寫項目的時候,用到的最多的部分可能就是Java的集合框架,經過閱讀集合框架源碼,瞭解其內部的數據結構實現,可以深刻理解各個集合的性能特性,而且可以幫助本身在從此的開發中避免犯一些使用錯誤。另外筆者本身也是摸着石頭過河,若是有描述不當的地方,但願園友們可以不吝指出,但願可以和你們共同進步!
java
能夠看到集合的基礎接口是Map, Collection以及Iterator。其他的類都實現自這3個類。segmentfault
public interface Iterator<E> { boolean hasNext(); E next(); default void remove() { throw new UnsupportedOperationException("remove"); } /** * 舉個簡單例子(把集合裏的元素每一個都輸出出來): * List<String> names = new ArrayList<>(); * names.add("Joemsu"); * names.add("GodnessY"); * names.iterator().forEachRemaining(c -> System.out.println("hi! " + c)); */ default void forEachRemaining(Consumer<? super E> action) { Objects.requireNonNull(action); while (hasNext()) action.accept(next()); } }
能夠看到Iterator接口仍是很簡單的,作到了見名知意,值得一提的是裏面的remove方法:此方法可用於在迭代中刪除結合中的元素,若是不用Iterator,在list循環中使用remove會拋異常。另外forEachRemaining()給出了簡單的例子,裏面的Consumer函數式接口有空再具體講解。
數組
public interface Collection<E> extends Iterable<E> { //值得一提的是:若是size超過Integer.MAX_VALUE也只會返回Integer.MAX_VALUE int size(); boolean isEmpty(); //若是向集合裏添加null,使用contains(null),也能夠返回true boolean contains(Object o); Iterator<E> iterator(); /** * 深層拷貝,修改數組的數據不會對集合裏的元素產生影響。 * 注意:只能返回Object[],不能強制轉換其餘類型,如須要轉型,使用下面帶泛型的方法。 */ Object[] toArray(); <T> T[] toArray(T[] a); boolean add(E e); boolean remove(Object o); boolean containsAll(Collection<?> c); boolean addAll(Collection<? extends E> c); boolean removeAll(Collection<?> c); //保留c集合裏的元素 boolean retainAll(Collection<?> c); void clear(); boolean equals(Object o); //如過a.equals(b),則hashCode()確定相同,反之不必定 int hashCode(); //針對parallelStream()添加的方法,用於分割集合,進行並行處理 @Override default Spliterator<E> spliterator() { return Spliterators.spliterator(this, 0); } /** * 若是知足filter,則刪除,舉個栗子: * Collection<String> myHeart = new ArrayList<>(); * myHeart.add("Boduolaoshi"); * myHeart.add("GodnessY"); * System.out.println("before: " + myHeart.size()); * myHeart.removeIf(s -> s.equals("Boduolaoshi")); * System.out.println("after: " + myHeart.size()); */ default boolean removeIf(Predicate<? super E> filter) { Objects.requireNonNull(filter); boolean removed = false; final Iterator<E> each = iterator(); while (each.hasNext()) { if (filter.test(each.next())) { each.remove(); removed = true; } } return removed; } default Stream<E> stream() { return StreamSupport.stream(spliterator(), false); } //採用並行處理,使用多核cpu的特性 default Stream<E> parallelStream() { return StreamSupport.stream(spliterator(), true); } }
須要注意的一些地方已經在註釋這裏特別說明過了,另外對於spliterator(),不是特別清楚的園友們,能夠點擊查看這裏,回答的已經很詳細了。
數據結構
public interface Map<K,V> { //一樣的,若是size超過Integer.MAX_VALUE也只會返回Integer.MAX_VALUE int size(); boolean isEmpty(); boolean containsKey(Object key); boolean containsValue(Object value); V get(Object key); V put(K key, V value); V remove(Object key); void putAll(Map<? extends K, ? extends V> m); void clear(); //對set的變更會影響到map,反過來也同樣 Set<K> keySet(); //對Collection的變更會影響到map,反過來也同樣 Collection<V> values(); //對Set的變更會影響到map,反過來也同樣 Set<Map.Entry<K, V>> entrySet(); boolean equals(Object o); int hashCode(); //Entry start interface Entry<K,V> { K getKey(); V getValue(); V setValue(V value); boolean equals(Object o); int hashCode(); //使用默認方法對Key進行比較 public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K,V>> comparingByKey(){ return (Comparator<Map.Entry<K, V>> & Serializable) (c1, c2) -> c1.getKey().compareTo(c2.getKey()); } //使用默認方法對Value比較 public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K,V>> comparingByValue() { return (Comparator<Map.Entry<K, V>> & Serializable) (c1, c2) -> c1.getValue().compareTo(c2.getValue()); } /** * 本身傳比較的方法,舉個栗子: * Map<String, Integer> map = new HashMap<>(); * map.put("sorted", 2); * map.put("collect", 1); * map.put("each", 3); * System.out.println("before sort"); * map.entrySet().forEach(System.out::println); * System.out.println("after sort"); * map.entrySet() * .stream() * .sorted(Map.Entry.comparingByKey((a, b) -> a.length() - b.length())) * .collect(Collectors.toList()).forEach(System.out::println); */ public static <K, V> Comparator<Map.Entry<K, V>> comparingByKey(Comparator<? super K> cmp) { Objects.requireNonNull(cmp); return (Comparator<Map.Entry<K, V>> & Serializable) (c1, c2) -> cmp.compare(c1.getKey(), c2.getKey()); } public static <K, V> Comparator<Map.Entry<K, V>> comparingByValue(Comparator<? super V> cmp) { Objects.requireNonNull(cmp); return (Comparator<Map.Entry<K, V>> & Serializable) (c1, c2) -> cmp.compare(c1.getValue(), c2.getValue()); } } //Entry end //獲取指定key 的value,沒有則返回默認值 default V getOrDefault(Object key, V defaultValue) { V v; return (((v = get(key)) != null) || containsKey(key)) ? v : defaultValue; } /** * 對每隊鍵值對操做: map.forEach((i, j) -> System.out.println(i + j)) * 注意這裏的(i, j)的類型與你初始化map的鍵值類型對應,i即K, j即V */ default void forEach(BiConsumer<? super K, ? super V> action) { Objects.requireNonNull(action); for (Map.Entry<K, V> entry : entrySet()) { K k; V v; try { k = entry.getKey(); v = entry.getValue(); } catch(IllegalStateException ise) { // this usually means the entry is no longer in the map. throw new ConcurrentModificationException(ise); } action.accept(k, v); } } /** * 傳入BiFunction類型,對每一個鍵值對進行處理,返回類型與V類型相同 * Map<String, Integer> map = new HashMap<>(); * map.put("hi", 3); * map.put("hello", 4); * BiFunction<String, Integer, Integer> bi = (a, b) -> a.length() + b; //爲了容易理解,這麼寫 * map.forEach((i, j) -> System.out.println(i + ":" + j)); * map.replaceAll(bi); * map.forEach((i, j) -> System.out.println(i + ":" + j)); */ default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) { Objects.requireNonNull(function); for (Map.Entry<K, V> entry : entrySet()) { K k; V v; try { k = entry.getKey(); v = entry.getValue(); } catch(IllegalStateException ise) { // this usually means the entry is no longer in the map. throw new ConcurrentModificationException(ise); } // ise thrown from function is not a cme. v = function.apply(k, v); try { entry.setValue(v); } catch(IllegalStateException ise) { // this usually means the entry is no longer in the map. throw new ConcurrentModificationException(ise); } } } //若是爲空的話,插入 default V putIfAbsent(K key, V value) { V v = get(key); if (v == null) { v = put(key, value); } return v; } default boolean remove(Object key, Object value) { Object curValue = get(key); if (!Objects.equals(curValue, value) || (curValue == null && !containsKey(key))) { return false; } remove(key); return true; } default boolean replace(K key, V oldValue, V newValue) { Object curValue = get(key); if (!Objects.equals(curValue, oldValue) || (curValue == null && !containsKey(key))) { return false; } put(key, newValue); return true; } default V replace(K key, V value) { V curValue; if (((curValue = get(key)) != null) || containsKey(key)) { curValue = put(key, value); } return curValue; } //若是key不存在,則經過mappingFunction生成value,並插入 default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) { Objects.requireNonNull(mappingFunction); V v; if ((v = get(key)) == null) { V newValue; if ((newValue = mappingFunction.apply(key)) != null) { put(key, newValue); return newValue; } } return v; } //若是存在key對應的值,則經過remappingFunction來計算新的value,(value不爲空)而後更新,爲空則刪除key default V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) { Objects.requireNonNull(remappingFunction); V oldValue; if ((oldValue = get(key)) != null) { V newValue = remappingFunction.apply(key, oldValue); if (newValue != null) { put(key, newValue); return newValue; } else { remove(key); return null; } } else { return null; } } default V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) { Objects.requireNonNull(remappingFunction); V oldValue = get(key); V newValue = remappingFunction.apply(key, oldValue); if (newValue == null) { // delete mapping if (oldValue != null || containsKey(key)) { // something to remove remove(key); return null; } else { // nothing to do. Leave things as they were. return null; } } else { // add or replace old mapping put(key, newValue); return newValue; } } //將舊的oldValue和新的傳進去value經過remappingFunction進行處理,而後更新 default V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) { Objects.requireNonNull(remappingFunction); Objects.requireNonNull(value); V oldValue = get(key); V newValue = (oldValue == null) ? value : remappingFunction.apply(oldValue, value); if(newValue == null) { remove(key); } else { put(key, newValue); } return newValue; } }
那麼Map的接口源碼閱讀就到這裏。
app
總的來講,jdk1.8集合與以前版本不一樣的地方就是加入了不少default方法,以及使用了各類函數型接口,但整體來講仍是比較好理解的。後面會更新其餘的實現類,謝謝各位園友觀看,若是有描述不對的地方歡迎指正。框架