1. Basic Introduction
1. Structure Diagram
2. Add Objects
Employee object added to the collection: Clerk
//Create an employee class public class Clerk { private String name;//Full name private int age;//Age private float sal;//wages public Clerk(String name,int age,float sal) { this.name=name; this.age=age; this.sal=sal; } //And get, set }
Set of List Structure
Description: Ordered, Repeatable
1. ArrayList class
ArrList implementation class: ArrayListDemo
import java.util.ArrayList; public class ArrayListDemo { public static void main(String[] args) { // Define ArrayList objects ArrayList al = new ArrayList(); // Display Size System.out.println("al Size:" + al.size()); test1(al);//Adding data to al test2(al);//Traversing data in al //test3(al); //Delete data in Al } private static void test3(ArrayList al) { // How to delete an object from al al.remove(1); System.out.println("===Remove Wu You==="); } private static void test2(ArrayList al) { // How to access objects (data) in al // Access the first object // Clerk temp=(Clerk)al.get(0); // System.out.println("First person's name is:"+temp.getName())); // Traverse all objects (data) of al for (int i = 0; i < al.size(); i++) { Clerk temp = (Clerk) al.get(i); System.out.println("Name:" + temp.getName()); } } private static void test1(ArrayList al) {//Adding data to al // Add data to all (type is Object) // Create a staff member Clerk clerk1 = new Clerk("Song River", 50, 1000); Clerk clerk2 = new Clerk("Wu Yong", 45, 1200); Clerk clerk3 = new Clerk("Lin Chong", 35, 1300); // Add clerk1 to al al.add(clerk1); al.add(clerk2); al.add(clerk3); // Can I put the same object? al.add(clerk1);//Yes? // Display Size System.out.println("al Size:" + al.size());//Output in sequence } }
Note: ArrayList is unsynchronized, thread insecure, can be added repeatedly, in order
2. LinkedList class
public class LinkedListDemo { static Clerk clerk1=new Clerk("sa01",33,1.2f); static Clerk clerk2=new Clerk("sa02",44,1.2f); static Clerk clerk3=new Clerk("sa03",66,1.2f); public static void main(String[] args) { // Define LinkedList object LinkedList ll=new LinkedList(); // Display Size System.out.println("ll Size:" + ll.size()); test1(ll);//Add data to ll test2(ll);//Delete data in ll } //Delete data in ll private static void test2(LinkedList ll) { //remove means deleting a piece of data ll.remove(clerk1);//Delete clerk1 data from ll System.out.println("test LinkedList In a collection class remove Method"); for(int i=0;i<ll.size();i++){ System.out.println(((Clerk)ll.get(i)).getName()); } ll.removeAll(ll);//Clear entire list System.out.println("test LinkedList In a collection class remmoveall Method"); for(int i=0;i<ll.size();i++){ System.out.println(((Clerk)ll.get(i)).getName());//Represents the clerk.get method } } //Add data to ll private static void test1(LinkedList ll) { //addFirst means the top of the load (chain list) queue for clerk1 ll.addFirst(clerk1);//The addFirst method can be inserted before and after an array:01 ll.addFirst(clerk2);//You can also understand that the addFirst method is a LIFO method, 02,01 //addLast means to load clerk3 behind the (linked list) queue ll.addLast(clerk3);//02,01,03 System.out.println("test LinkedList In a collection class addFist and addLast Method"); for(int i=0;i<ll.size();i++){//Output: 02, 01, 03 System.out.println(((Clerk)ll.get(i)).getName()); } } }
Note: Use a list of chains to exit from the front of the queue
3. Vector class
public class VectorDemo { public static void main(String[] args) { //Usage of Vector Vector vv=new Vector(); text1(vv);//Add data to vv text2(vv);//Traversing data in vv } private static void text2(Vector vv) { //ergodic for(int i=0;i<vv.size();i++){ Clerk clerk=(Clerk)vv.get(i); System.out.println(clerk.getName()); } } private static void text1(Vector vv) { Clerk clerk1=new Clerk("1",23,1.2f); Clerk clerk2=new Clerk("2",55,1.2f); Clerk clerk3=new Clerk("3",34,1.2f); vv.add(clerk1); vv.add(clerk2); vv.add(clerk3); vv.add(clerk1); } }
Note: Thread security is synchronized
4. Stack class
//Use of Stack Collection Class (Stack) public class StackDemo { public static void main(String[] args) { // TODO Auto-generated method stub // Use of Stack Stack stack = new Stack(); Clerk clerk1 = new Clerk("s1", 21, 1.2f); Clerk clerk2 = new Clerk("s2", 23, 1.2f); stack.add(clerk1); stack.add(clerk2); stack.add(clerk2); for (int i = 0; i < stack.size(); i++) { System.out.println(((Clerk) stack.get(i)).getName()); } } }
3. Collection of Map Structures
1. HashMap classes
public class HashMapDemo { public static void main(String[] args) { //Create HashMap Object HashMap hm=new HashMap(); test1(hm);//Add data to hm test2(hm);//Find data in hm } private static void test2(HashMap hm) { //If you are looking for number s002 if(hm.containsKey("s002")){//Keyvalue containsKey System.out.println("Has this employee"); //How to remove, key <key>value Clerk clerk=(Clerk)hm.get("s002"); System.out.println("Name"+clerk.getName()); }else{ System.out.println("No such employee"); } //Traverse all key and value values in HashMap //Iterator iteration Iterator it=hm.keySet().iterator(); //hasNext returns a boolean value while(it.hasNext()){ //If there is next key value to take out String key=it.next().toString(); //Remove value by key Clerk clerk=(Clerk)hm.get(key); System.out.println("Name:"+clerk.getName()); System.out.println("Wages:"+clerk.getSal()); } } private static void test1(HashMap hm) { Clerk clerk1=new Clerk("s001",21,3.4f); Clerk clerk2=new Clerk("s002",22,5.6f); Clerk clerk3=new Clerk("s003",23,1.2f); //Place Clerk in hm //hm.put(null,null); //can empty values hm.put("s001", clerk1); hm.put("s002", clerk2); hm.put("s002", clerk3);//key duplication is not allowed, so Clerk3 will override Clerk2 } }
Note: Because hashing is used, all values are not taken out in order
2. Hashtable class
public class HashtableDemo { public static void main(String []args){ Hashtable ht=new Hashtable();//Hashtable and HsahMap are used in the same way test1(ht);//Add to test2(ht);//ergodic } private static void test2(Hashtable ht) { for(Iterator it=ht.keySet().iterator();it.hasNext();){ String key=it.next().toString(); Clerk clerk=(Clerk)ht.get(key); System.out.println("Name:"+clerk.getName()+"\t Wages:"+clerk.getSal()); } } private static void test1(Hashtable ht) { Clerk clerk4=new Clerk("s101",22,2.2f); Clerk clerk5=new Clerk("s102",32,1.2f); Clerk clerk6=new Clerk("s103",32,4.2f); ht.put("s101", clerk4); ht.put("s102", clerk5); ht.put("s103", clerk6); } }
Note: Hashtable is synchronous and thread safe
3. Differences between HashMap and Hashtable
- Historical reason: Hashtable is based on the old Dictionary class, HashMap is an implementation of the Map interface introduced by java 1.2.
- Synchronization: Hashtable is thread synchronized.Some methods in this class ensure that objects in Hashtable are thread-safe.HashMap is thread asynchronous, so objects in HashMap are not thread safe.Since the requirement of synchronization can affect the efficiency of execution, using HashMap is a good option if you do not need a thread-safe collection to avoid unnecessary performance overhead due to synchronization and increase efficiency.
- value: HashMap allows you to use null values as key s or values for a table entry, but Hashtable cannot put null values.
Set structured set classes
1. HashSet class
HashSet is based on HashMap, where the bottom uses HashMap to hold all elements.
public class HashSetDemo { public static void main(String []args){ HashSet<Clerk> hs=new HashSet<Clerk>(); test1(hs);//Add data to hs test2(hs);//ergodic } private static void test2(HashSet<Clerk> hs) { //Convert array o[], traverse and output null in HashSet Object o[]=hs.toArray(); for(int i=0;i<o.length;i++){ System.out.println("Full name:"+((Clerk)o[i]).getName()+"\t Age:"+((Clerk)o[i]).getAge()+"\t wages:"+((Clerk)o[i]).getSal()); } } private static void test1(HashSet<Clerk> hs) { Clerk clerk1=new Clerk("s001",21,1.2f); Clerk clerk2=new Clerk("s002",22,1.6f); Clerk clerk3=new Clerk("s003",23,1.8f); Clerk clerk4=new Clerk("s001",24,1.2f); hs.add(clerk1); hs.add(clerk2); hs.add(clerk3); hs.add(clerk4); hs.add(clerk1);//Duplicate clerk1,HashSet automatically removes System.out.println("HashSet_size="+hs.size()); System.out.println(); ArrayList<Clerk> al=new ArrayList<Clerk>(); Clerk clerk5=new Clerk("s004",33,1.0f); Clerk clerk6=new Clerk("s005",14,2.5f); al.add(clerk5); al.add(clerk6); //al.add(clerk1); hs.addAll(al);//Add values from al to hs and remove duplicate clerk1 System.out.println("HashSet_ArrayList_size="+hs.size()); System.out.println(); } }
2. TreeSet class
The TreeSet collection class is an ordered collection whose elements are sorted in ascending order and by default in natural order, meaning that the object elements in the TreeSet need to implement the Comparable interface.Like the HashSet class, TreeSet does not have a get() method to get elements in the list, so it can only be obtained by an iterator method.TreeSet is implemented by TreeMap. TreeSet is an ordered collection whose elements are arranged in ascending order and by default in natural order. That is, the object elements in TreeSet need to implement Comparable interface
Note: Since TreeMaps need to be sorted, a Comparator is required to compare the size of key values, and of course a Comparator located with a Comparator can be specified when creating a TreeMap, using Comparator.compare when sorting.If a Comparator is not specified at creation time, the key.compareTo() method is used, which requires that the key implement the Comparable interface.TreeMap is implemented using Tree data structures, so you can complete the positioning using the compare interface.The object classes it operates on are as follows:
//Create Strudent Student Class and Implement Comparable and Comparator Interface class Student implements Comparable,Comparator{ private int num;//Define School Number private String name;//Define Name public Student(int num,String name){ this.num=num; this.name=name; } public int compareTo(Object o){ Student st=(Student)o; int result; result=num>st.num?1:(num==st.num?0:-1);//Determine if the number is the same and return the result value //If the numbers are equal, they are listed by name /* if(result==0){ return name.compareTo(st.name); }*/ return result; } //Implement the Comparator interface and implement its abstract method public int compare(Object o1,Object o2){ Student st1 =(Student)o1; Student st2 =(Student)o2; return st1.name.compareTo(st2.name);//Compare names } //Rewrite the toString() method, because if you don't override it, you print out 16-bit code public String toString(){ return "num="+num+"; name="+name; } public static class StudentComparator implements Comparator{//Define a static StudentComparator class and implement the Comparator interface public int compare(Object o1,Object o2){ Student st1 =(Student)o1; Student st2 =(Student)o2; int result; result=st1.num>st2.num?1:(st1.num==st2.num?0:-1);//Determine if the numbers are the same for sorting if(result==0){//Sort names if numbers are equal result=st1.name.compareTo(st2.name); } return result; } } }
The TreeSet class is then used as follows:
public class TreeSetDemo{ public static void main(String[] args){ //Pass a comparator to achieve your own sorting TreeSet tr =new TreeSet(new Student.StudentComparator()); tr.add(new Student(301,"Zhang San"));//Write student data to tr of TreeSet collection class tr.add(new Student(201,"Li Er")); tr.add(new Student(101,"King Five")); tr.add(new Student(101,"Poor One")); Iterator it=tr.iterator();//Iterator, traversal while(it.hasNext()){//Determine if there is next element System.out.println(it.next()); } } }
5. Comparison of Three Collection Structures
1. Overall
- List saves objects in the order they entered, without sorting or editing.
- Sets accept each object only once and use their own internal sorting method (typically, you only care if an element belongs to a Set and not its order -- otherwise, use List).
- Maps also keep a copy of each element, but this is based on keys, and Maps also have built-in sorting, so they don't care about the order in which elements are added.If the order in which elements are added is important to programming, you should use LinkedHashSet or LinkedHashMap.
2. Specific
1.List's Functional Methods
There are actually two lists: one is the basic Array List, which has the advantage of random access to elements, and the other is the more powerful LinkedList, which is not designed for quick random access, but has a more general set of methods.
- List: Order is the most important feature of List: it guarantees that elements are maintained in a specific order.List adds a number of methods to Collection that allow you to insert and remove elements into the middle of a List (this is only recommended for LinkedList s). A List can generate a Listlterator that can be used to traverse a List in two directions or insert and remove elements from the middle of a List.
- ArrayList: List implemented by an array.Quick random access to elements is allowed, but inserting and removing elements from the middle of the list is slow.Listlterator should only be used to traverse ArrayList from back to forward.Instead of inserting and removing elements.That's because it's much more expensive than LinkedList.
- LinkedList: Sequential access is optimized and inserting and deleting into the middle of the List is not expensive.Random access is relatively slow.(instead of using ArrayList) also has the following methods: addFirst(), addLast(), getFirst(), getLast(), removeFirst(), and removeLast() which are not defined in any interface or base class so that LinkedList can be used as a stack, queue, and two-way queue.
2. Functional Methods of Set
Set has the exact same interface as Collection, so it does not have any additional functionality unlike the two previous lists.Set is actually a Collection, but behaves differently.(This is a classic application of inheritance and polymorphism: displaying different behaviors.Set does not save duplicate elements (more responsible for how to judge that elements are the same)
- Set: Each element stored in a Set must be unique, because a Set does not save duplicate elements.Elements that join a Set must define an equals() method to ensure the uniqueness of the object.Set has exactly the same interface as Collection.Set interfaces do not guarantee the order in which elements are maintained.
- HashSet: Set designed for fast find.Objects stored in a HashSet must define hashCode().
- TreeSet: A set that holds the order, with a tree structure at the bottom.Use it to extract ordered sequences from a Set.
- LinkedHashSet: HashSet query speed, and internal use of the chain table to maintain the order of elements (insertion order).When iterators are used to iterate through Sets, the results are displayed in the order in which the elements are inserted.
3. Functional methods of Map
The method put(Object key,Object value) adds a value (want something) and a key (use it to find) associated with the value.The method get(Object key) returns the Value associated with a given Key.You can use containsKey() and containsValue() to test if a Map contains a key or value.The standard java class library contains several different Maps: HashMap, TreeMap, LinkedHashMap, WeakHashMap, ldentityHashMap.They all have the same basic interface Map, but differ in behavior, efficiency, sorting strategy, lifecycle of objects, and key-equivalent decision strategies.
Efficiency of execution is a big problem with Map.Looking at what get() does, you can see why searching for "keys" in an ArrayList is so slow.This is where HashMap speeds up.HashMap uses special values, called hash codes, to replace slow searches for keys.A hash code is a "relatively unique" int value that represents an object and is generated by converting some of the object's information.All java objects can produce hash codes because hashCode() is a method defined in the base class Object.HashMap is a fast query using the hashCode () of the object.This method can significantly improve performance.
- Map: Maintains the relevance of key-value pairs so that you can find values through keys
- HashMap: A hash-based implementation of Map.The cost of inserting and querying key-value pairs is fixed.Capacity capacity and load factor can be set through the constructor to adjust container performance.
- LinkedHashMap: Similar to HashMap, but when iterating through it, the order in which the "key-value pairs" are obtained is the order in which they are inserted, or the order in which they are least recently made (LRU).Only HashMap can be slower.It is faster when iterating over, because it uses key tables to maintain internal order.
- TreeMap: Implementation based on red and black tree data results.When you look at Key or Key Value Pairs, they are sorted (the order is determined by Comparabel or Comparator).TreeMap is characterized by ordered results.TreeMap is the only Map with a subMap() method that returns a subtree.
- WeakHashMap: Weak key Map, where objects used are also allowed to be released: this is designed to solve a particular problem.If no references other than map point to a key, the key can be recycled by the garbage collector.
- ldentifyHashMap: A hash map that compares keys using ==instead of equals().Designed to solve special problems.
6. Other Miscellaneous Items
1. Detailed method of adding or deleting
The java.util package contains a series of important collection classes, the root interface Collection of collection classes.The Collection interface is the root type of all collection classes.One of its main interface methods is:
boolean add(Object c)//Add data
The add() method adds a new element.Note that this method returns a boolean, but the return value does not indicate whether the addition was successful or not.Collection specifies that if a collection refuses to add this element, an exception must be thrown for any reason.The meaning of this return value is whether the content of the collection has changed (i.e., the elements have an infinite number, positions, etc.) after the add() method is executed, which is achieved by a specific class.That is, if a method fails, an exception is always thrown; the return value simply indicates whether the Collection's content has changed since the method was executed.Similarly, there are:
boolean addall(Collection c);//Add All Data boolean remove(Object o);//Delete data boolean removeall(Collection c);//Delete all data boolean remainall(Collection c);//Keep all data
The Object[]toArray() method is simple, converting a collection to an array and returning it.The Object[]toArray(Object[] a) method is a bit complicated. First, the returned Object [] still turns all the elements of the collection into arrays, but the types of the type and parameter a are the same.For example:
String[] o=(String)c.toArray(new String[0]);//The resulting o actual type is a String[] array
Second, if parameter a does not fit all the elements of the set, a new array will be returned.If the size of parameter a holds all the elements of the collection, it returns a, but the content of a is populated with the elements of the collection.It is important to note that if a is larger than the number of elements in the collection, all the parts that follow a are null (empty).
2. Use of iterators
The Iterator mode is a standard access method for traversing collection classes.It can abstract access logic from different types of collection classes, thereby avoiding exposing the internal structure of the collection to clients.For example, if Iterator is not used, the way to traverse an array is to use an index:
for(int i=0;i<array.size();i++) {..get(i)...}
To access a LinkedList, you must use a while loop:
while((e=e.next())!=null) {...e.data()...}
Clients of both methods must know the internal structure of the collection beforehand. The access code and the collection itself are tightly coupled and cannot separate the access logic from the collection class and the client code. Each collection corresponds to a traversal method and the client code cannot be reused.Even more frightening, if you later need to change ArrayList to LinkedList, the original client code must be completely rewritten.To solve these problems, the Iterator pattern always traverses the collection with the same logic:
for(Iterator it=c.iterater();it.hasNext();){ ...}
The secret is that the client itself does not maintain a "pointer" to traverse the collection, and all internal states (such as the current element location, whether there is a next element) are maintained by the Iterator, which is generated by the collection class through the factory method, so it knows how to traverse the entire collection.Clients never deal directly with a collection class; they always control Iterator and send it commands to "Forward", "Backward", "Take Current Element", which indirectly traverse the entire collection.First look at the definition of the java.util.Iterator interface:
public interface Iterator { boolean hasNext(); Object next(); void remove(); }
Depend on the first two methods to complete the traversal, typical code is as follows:
for(Iterator it=c.iterator();it.hasNext();){ Object o=it.next(); // Operations on o... }
Each collection class may return a different Iterator specific type, Array may return ArrayIterator, Set may return SetIterator, Tree may return TreeIterator, but they all implement the Iterator interface, so the client does not care which Iterator it is, it only needs to acquire this Iterator interface, which is the object-oriented power.
To ensure the successful completion of the traversal process, you must ensure that the contents of the collection are not changed during the traversal process (except for the Iterator's remove() method), so the principle of reliable traversal is to use the collection only in one thread or to synchronize the traversal code in multiple threads.
Iterator example:
Collection c=new ArrayList(); c.add("abc"); c.add("xyz"); for(Iterator it:c){ String s=(String)it.next(); System.out.println(s); }
If you replace the Array List of the first line of code with a LinkedList or Vector, the rest of the code can be compiled without changing one line and without changing the functionality, which is the principle for abstract programming: minimal dependency on specific classes.
3. Introduction to Queue
The Queue interface, at the same level as List and Set, inherits the Collection interface.LinkedList implements the Queue interface.The Queue interface narrows access to LinkedList's methods (that is, when the parameter type in the method is Queue, only the methods defined by the Queue interface can be accessed, not the non-Queue methods directly), so that only the appropriate methods can be used.BlockingQueue inherits the Queue interface.
A queue is a data structure.It has two basic operations: adding an element at the end of the queue and removing an element from the head of the queue.That is, a queue manages data in a first-in-first-out manner, which can cause a thread to block if you try to add an element to a full blocked queue or remove a tuple from an empty blocked queue.
Blocking queues is a useful tool for multithreaded collaboration.Worker threads can periodically store intermediate results in blocked queues while other worker line threads pull them out and modify them in the future.The queue automatically balances the load.If the first set of threads runs slower than the second, the second set of threads will become blocked while waiting for results.If the first thread set runs fast, it will wait for the second thread set to catch up.
Queue blocking operations can be categorized into three categories based on how they respond: add, remove, and element operations throw exceptions when you attempt to add elements to a full queue or get elements from an empty queue.Of course, in a multi-threaded program, the queue can become full or empty at any time, so you might want to use offer, poll, peek methods.These methods only give an error when the task cannot be completed without throwing an exception.
Note: The poll and peek methods return null in error.Therefore, it is illegal to insert a null value into a queue.
The methods for queuing are:
add | Add an element | If the queue is full, throw an IIIegaISlabEeplian exception |
remove | Remove and return elements from the header of the queue | If the queue is empty, a NoSuchElementException exception is thrown |
element | Returns the element at the head of the queue | If the queue is empty, a NoSuchElementException exception is thrown |
offer | Add an element and return true | Return false if the queue is full |
poll | Remove and ask back the element at the head of the queue | Returns null if the queue is empty |
peek | Returns the element at the head of the queue | Returns null if the queue is empty |
put | Add an element | Block if queue is full |
take | Remove and return elements from the header of the queue | Block if queue is empty |
Note: remove, element, offer, poll, peek are really Queue interfaces.The differences between these methods are:
- Offer, add difference: Some queues have size limitations, so if you want to add a new item to a full queue, the extra items will be rejected.The new offer method works.Instead of throwing an unchecked exception on the call to the add() method, it simply gets false returned by offer().
- Poll, remove difference: both remove () and poll () methods delete the first element (head) from the queue.remove() behaves similarly to the version of the Collection interface, but the new poll() method does not throw an exception when called with an empty collection, it just returns null.Therefore, the new method is more suitable for cases where abnormal conditions are prone to occur.
- Peek, element difference: element() and peek() are used to query elements at the head of the queue.Similar to the remove() method, element() throws an exception when the queue is empty, and peek() returns null.
Each of the five queues offers a different choice:
- ArrayBlockingQueue: A bounded queue supported by an array.The elements are sorted based on the FIFO principle on the blocking loop queue of the array.
- LinkedBlockingQueue: An optionally bounded queue supported by a link node.A first-in-first-out sorting element based on a chain table queue.
- PriorityBlockingQueue: An unbounded priority queue supported by a priority heap.PriorityBlockingQueue is a repackaging of PriorityQueue based on heap data structure, and PriorityQueue has no capacity restrictions, just like ArrayList, so it is not blocked when put ting on a priority blocking queue.However, since resources are exhausted, attempting to perform an add operation may result in OutOfMemoryError, but if the queue is empty, the element fetch operation take will block, so its retrieval operation take is blocked.Additionally, elements entering the queue need to be comparable.
- DelayQueue: A time-based scheduling queue supported by a priority heap.(Implemented based on PriorityQueue) is an unbounded blocking queue that holds Delayed elements and extracts them only when the delay expires.The header of the queue is the Delayed element that lasts the longest after the delay expires.If the delay has not expired, the queue has no head, and poll returns null.When an element's getDelay(TimeUnit.NANOSECONDS) method returns a value less than or equal to zero, the expiration occurs and poll removes the element.Null elements are not allowed in this queue.
- SynchronousQueue: A simple rendezvous mechanism that leverages the BlockingQueue interface.The SynchronousQueue class is the simplest.It has no internal capacity.It's like handing over between threads.The producer who adds an element to the queue waits for the consumer of another thread.When this consumer appears, this element is passed directly between the consumer and the producer and never joins the blocking queue.
Note: Queue queues cannot be instantiated directly.In java programming, Queue is implemented using LinkedList.For example:
Queue qe=new LinkedList();
Note: This implementation is not synchronous.If multiple threads access a list of links at the same time and at least one of them has structurally modified the list, it must guarantee external synchronization.(Structural modification refers to any action that adds or deletes one or more elements; setting only the value of an element is not a structural modification.) This is usually done by synchronizing objects that naturally encapsulate the list.