Thinking in Java——筆記(17)

来源:http://www.cnblogs.com/apolloqq/archive/2016/12/21/6208841.html
-Advertisement-
Play Games

Containers in Depth ___ Full container taxonomy You can usually ignore any class that begins with "Abstract." Filling containers This fill( ) just dup ...


Containers in Depth


Full container taxonomy

  • You can usually ignore any class that begins with "Abstract."

Filling containers

  • This fill( ) just duplicates a single object reference throughout the container. In addition, it only works for List objects.
  • The fill( ) method is made even less useful by the fact that it can only replace elements that are already in the List and will not add new elements.

A Generator solution

  • Virtually all Collection subtypes have a constructor that takes another Collection object, from which it can fill the new container.
  • A LinkedHashSet maintains a linked list holding the insertion order.

Using Abstract classes

  • Each java.util container has its own Abstract class that provides a partial implementation of that container, so all you must do is implement the necessary methods in order to produce the desired container.
  • You use a flyweight when the ordinary solution requires too many objects, or when producing normal objects takes up too much space.

Collection functionality

  • There’s no get( ) method for random-access element selection.
  • Thus, if you want to examine the elements of a Collection, you must use an iterator.

Optional operations

  • The implementing class is not required to provide functioning definitions for these methods.
  • An "optional" operation says that calling some methods will nor perform meaningful behavior.
  • If an operation is optional, the compiler still restricts you to calling only the methods in that interface.
  • Unsupported operations are a special case that can be delayed until necessary.
  • The design does provide a "back door" if you want to create a new Collection without providing meaningful definitions for all the methods in the Collection interface, and yet still fit it into the existing library.

Unsupported operations

  • Because Arrays.asList( ) produces a List that is backed by a fixed-size array, it makes sense that the only supported operations are the ones that don’t change the size of the array.
  • Arrays.asList( ) returns a fixed-sized List, whereas Collections.unmodifiableList( ) produces a list that cannot be changed.

Sets and storage order

  • A Set needs a way to maintain storage order.
  • Different Set implementations not only have different behaviors, they have different requirements for the type of object that you can put into a particular Set.
  • In the absence of other constraints, HashSet should be your default choice because it is optimized for speed.
  • The HashSet keeps the elements in some mysterious order.
  • The LinkedHashSet keeps the elements in the order in which they were inserted.
  • The TreeSet maintains the elements in sorted order.
  • The only reliable way to ensure the correctness of such a program is to incorporate unit tests into your build system.

SortedSet

  • Note that SortedSet means "sorted according to the comparison function of the object," not "insertion order."

Queues

  • With the exception of the priority queues, a Queue will produce elements in exactly the same order as they are placed in the Queue.
  • There are methods in LinkedList that support deque operations, but there is no explicit interface for a deque in the Java standard libraries.
  • You can create a Deque class using composition, and simply expose the relevant methods from LinkedList.

Understanding Maps

  • The standard Java library contains different basic implementations of Maps: HashMap, TreeMap, LinkedHashMap, WeakHashMap, ConcurrentHashMap, and IdentityHashMap.
  • The number of implementations of the Map interface should tell you something about the importance of this tool.
  • The keys are guaranteed to be in sorted order in SortedMap.
  • A LinkedHashMap can be configured in the constructor to use a leastrecently- used (LRU) algorithm based on accesses, so elements that haven’t been accessed (and thus are candidates for removal) appear at the front of the list.

Performance

  • Instead of a slow search for the key, it uses a special value called a hash code.
  • In the absence of other constraints, HashMap should be your default choice because it is optimized for speed.
  • Note that keys must be unique, but values may contain duplicates.

Hashing and hash codes

  • It is Object’s hashCode( ) method that is used to generate the hash code for each object. By default this just uses the address of its object.
  • equals( ) is used by the HashMap when trying to determine if your key is equal to any of the keys in the table.
  • The default Object.equals( ) simply compares object addresses.
  • To use your own classes as keys in a HashMap, you must override both hashCode( ) and equals( ).
  • The hashCode( ) is not required to return a unique identifier.

Hashing for speed

  • One of the solutions to the problem is to keep the keys sorted and then use Collections.binarySearch( ) to perform the lookup.
  • From the key object, a number will be derived that will index into the array.
  • To solve the problem of the fixed-size array, more than one key may produce the same index.
  • It doesn’t matter how big the array is; any key object’s hash code will land somewhere in that array.
  • If you could guarantee that there were no collisions (which is possible if you have a fixed number of values), then you’d have a perfect hashing junction, but that’s a special case.
  • Instead of searching through the entire list, you quickly jump to a slot where you only have to compare a few entries to find the value.

Overriding hashCode()

  • You don’t control the creation of the actual value that’s used to index into the array of buckets.
  • Regardless of when hashCode( ) is called, it produces the same value for a particular object every time it is called.
  • You’ll want to use information in the object that identifies the object in a meaningful way.
  • It makes sense that the hashCode( ) produced by two separate instances of the String "hello" should be identical.
  • For a hashCode( ) to be effective, it must be fast and it must be meaningful; that is, it must generate a value based on the contents of the object.
  • A good hashCode( ) should result in an even distribution of values.
  • Writing a proper hashCode( ) and equals( ) for a new class can be tricky.

Choosing an implementation

  • The distinction between containers often comes down to what they are "backed by"—that is, the data structures that physically implement the desired interface.
  • You choose the implementation based on the behavior you need.
  • One way to look at the differences between container implementations is with a performance test.

Choosing between Lists

  • Clearly, linked lists are not a good choice if you will be performing many random accesses.
  • An ArrayList must create space and copy all its references forward during an insertion. This becomes expensive as the ArrayList gets bigger.
  • The output that the cost of insertion and removal in a LinkedList is quite cheap and doesn’t vary with the list size, but with an ArrayList, insertions especially are very expensive, and the cost increases with list size.
  • The best approach is probably to choose an ArrayList as your default and to change to a LinkedList if you need its extra functionality or you discover performance problems due to many insertions and removals from the middle of the list.
  • If you are working with a fixed-sized group of elements, either use a List backed by an array (as produced by Arrays.asList( )), or if necessary, an actual array.

Microbenchmarking dangers

  • When writing so-called microbenchmarks, you must be careful not to assume too much, and to narrow your tests so that as much as possible they are only timing the items of interest.
  • You should not be so concerned with absolute numbers as with the performance comparisons between one type of container and another.

Choosing between Sets

  • The performance of HashSet is generally superior to TreeSet, but especially when adding elements and looking them up, which are the two most important operations.
  • TreeSet exists because it maintains its elements in sorted order, so you use it only when you need a sorted Set.

Choosing between Maps

  • Insertions for all the Map implementations except for IdentityHashMap get significantly slower as the size of the Map gets large.
  • lookup is much cheaper than insertion.
  • A TreeMap is a way to create an ordered list.
  • When you’re using a Map, your first choice should be HashMap, and only if you need a constantly sorted Map will you need TreeMap.

HashMap performance factors

  • HashMap and HashSet have constructors that allow you to specify the load factor.
  • When this load factor is reached, the container will automatically increase the capacity (the number of buckets) by roughly doubling it and will redistribute the existing objects into the new set of buckets (this is called rehashing).
  • The default load factor used by HashMap is 0.75.
  • A higher load factor decreases the space required by the table but increases the lookup cost.

Utilities

  • Use a ListIterator to trim off the last elements.
  • If you sort using a Comparator, you must binarySearch( ) using the same Comparator.
  • The Collections class allows you to do this by passing the original container into a method that hands back a read-only version.
  • You must fill the container with meaningful data before you make it read-only.
  • Once it is loaded, the best approach is to replace the existing reference with the reference that is produced by the "unmodifiable" call.
  • The Collections class contains a way to automatically synchronize an entire container.
  • It is best to immediately pass the new container through the appropriate "synchronized" method.
  • The Java containers library uses a fail-fast mechanism that looks for any changes to the container other than the ones your process is personally responsible for.

Holding references

  • There are three classes inherited from the abstract class Reference: SoftReference, WeakReference, and PhantomReference.
  • You have an ordinary reference on the stack that goes right to the object, but you might also have a reference to an object that has a reference to the object in question.
  • If an object isn’t reachable, there’s no way for your program to use it, so it’s safe to garbage collect that object.
  • If the garbage collector discovers that an object is reachable through an ordinary reference, it will not release that object.
  • In the order of SoftReference, WeakReference, and PhantomReference, each one is "weaker" than the last and corresponds to a different level of reachability.

The WeakHashMap

  • In such a mapping, you are saving storage by creating only one instance of a particular value. When the program needs that value, it looks up the existing object in the mapping and uses that.

Java 1.0/1.1 containers

  • Although you should never use the old containers when writing new code, you’ll still need to be aware of them.

Vector & Enumeration

  • Even though you should always use Iterator when you can in your own code, you must be prepared for libraries that want to hand you an Enumeration.

HashTable

  • There’s no reason to use Hashtable instead of HashMap in new code.

Stack

  • It has all of the characteristics and behaviors of a Vector plus some extra Stack behaviors.
  • By virtue of inheritance, a Stack is a Vector. Thus, all operations that can be performed on a Vector can also be performed on a Stack.

BitSet

  • You’re better off creating your own class, or just an array, to hold your flags if size is an issue.
  • An EnumSet is usually a better choice than a BitSet if you have a fixed set of flags that you can name.
    

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 線程可以理解為下載的通道,一個線程就是一個文件的下載通道,多線程也就是同時開啟好幾個下載通道。當伺服器提供下載服務時,使用下載者是共用帶寬的,在優先順序相同的情況下,總伺服器會對總下載線程進行平均分配。不難理解,如果你線程多的話,那下載的越快。 現流行的下載軟體都支持多線程,且支持中途暫停下載,再次開 ...
  • 如果運行後如圖的錯,需要進行如下操作來解決: a:打開cmd,輸入netstat -ano 找到本地地址為8080的最後一項的數字,這個數字就是埠號。 b:再輸入taskkill /t /pid 埠號數字 /f 來關閉此進程。 c:註意每個命令後面不要加 ; 結尾,運行以上命令再重新運行工程即可 ...
  • 本文地址 可以拜讀: 從零開始學 Java 分享提綱: 1.java數據結構 1. java數據結構 1)【概述】 Java工具包提供了強大的數據結構。在Java中的數據結構主要包括以下幾種介面和類: 枚舉(Enumeration) 位集合(BitSet) 向量(Vector) 棧(Stack) 字 ...
  • 1、sdk返回值不是int型 1.1 登錄函數調用 def login(ip, port, username, password, device_info, error_code):"""LLONG CLIENT_Login(char *pchDVRIP, WORD wDVRPort,char *p... ...
  • 其實也沒啥好說的 用樹狀數組可以O(logn)的查詢 套一層整體二分就可以做到O(nlngn) 最後用樹鏈剖分讓序列上樹 ...
  • 這裡給大家詳細說一下Maven的運行機制,讓大家不僅知其然,更知其所以然。 1.插件保存在哪裡? 與我們所依賴的構件一樣,插件也是基於坐標保存在我們的Maven倉庫當中的。在用到插件的時候會先從本地倉庫查找插件,如果本地倉庫沒有則從遠程倉庫查找插件並下載到本地倉庫。 與普通的依賴構件不同的是,Mav ...
  • Java是一門面向對象的語言,那麼我們寫程式的時候最經常操作的便是對象了,為此,Java提供了一些專門用來處理對象的類庫,這些類庫的集合我們稱之為集合框架。Java集合工具包位於Java.util包下,包含了很多常用的數據結構,如數組、鏈表、棧、隊列、集合、哈希表等。學習Java集合框架下大致可以分 ...
  • 首先在頁面中我們直接寫一個標簽,然後給標簽定義一個id,這裡我們用什麼標簽都可以,我們就用<span></span>演示吧, 代碼如下: 上面我們實例化了一個Clock的對象,這裡我們就在外部定義一個Clock的類, 獲取當前時間併進行時間的格式化,代碼如下: 之後我們在頁面頭部中引入該js就好了: ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...