Collection introduction
Insufficient array
- The length must be specified at the beginning and cannot be changed once specified
- Saved elements must be of the same type
- Using arrays to add elements is troublesome
aggregate
-
You can dynamically save any number of objects
-
It provides a series of methods to operate objects conveniently: add, remove, set and get
Single column set system diagram
Two column set system diagram
Collection interface and common methods
Characteristics of Collection interface implementation class
public interface Collection<E> extends Iterable<E>
- Collection implementation subclass can store multiple elements, and each element can be an Object
- Some Collection implementation classes can store duplicate elements, while others cannot
- Some Collection implementation classes, some are ordered (List), and some are not ordered (Set)
- The Collection interface does not directly implement subclasses, but is implemented through its sub interfaces Set and List
Collection method
//Collection is an interface and cannot be instantiated, //Here we take its implementation subclass ArrayList as an example List list = new ArrayList(); // add adds a single element list.add("Zhang San"); list.add(18);//list.add(new Integer(18));// In essence, the basic data type is automatically boxed into the corresponding packing class object and stored in the list.add('male');//list.add(new Character('male '); System.out.println(list); // remove deletes the specified element // list.remove("Zhang San")// remove(Object o); Specifies to delete an element list.remove(0);//remove(int index); Delete by index System.out.println(list); // contains finds whether the element exists System.out.println(list.contains("Zhang San")); System.out.println(list.contains(new Integer(18))); // size gets the number of elements System.out.println(list.size()); // isEmpty determines whether it is empty or null System.out.println(list.isEmpty()); // Clear clear all elements list.clear(); System.out.println(list); // addAll add multiple elements ArrayList list2 = new ArrayList(); list2.add("Java From getting started to giving up"); list2.add("C++From entry to becoming a monk"); list.addAll(list2); System.out.println(list); // coltainsAll finds whether multiple elements exist System.out.println(list.containsAll(list2)); // removeAll deletes multiple elements list.add("pantheon "); list.removeAll(list2); System.out.println(list);
Traversal mode 1 - use Iterator
Basic introduction
- The Iterator object is called an Iterator and is mainly used to traverse the elements in the Collection
- All Collection classes that implement the Collection interface have an iterator() method to return an object that implements the Iterator interface, that is, an Iterator can be returned
- The Iterator is only used to traverse the collection, and the Iterator itself does not store objects
Collection col = new ArrayList(); //Iterator traversal // First get the iterator corresponding to col Iterator iterator = col.iterator(); // Use the while loop to traverse hasNext()// Determine if there is a next element while(iterator.hasNext()) { // Object obj = iterator.next();//next(); 1. Move the pointer down 2. Return the element at the collection position after moving down System.out.println(iterator.next()); } //Note: you must call hasNext() before calling next(); Test; //If next(); If there is no element behind, an exception NoSuchElementException will be thrown // iterator.next(); //After the while loop, the iterator iterator, which points to the last element //So to change the variable again, you need to reset the iterator iterator = col.iterator(); System.out.println("============Second traversal==========="); while(iterator.hasNext()) { System.out.println(iterator.next());
Traversal mode 2 - enhanced with a for loop
Enhanced for loop can replace iterator iterator. Features: for enhancement is a simplified version of iterator. It is inherently foreign and can only be used to traverse sets or arrays
Collection col = new ArrayList(); // Enhance for, and the underlying is still an iterator // Enhanced for can be understood as a simplified version of iterator traversal for (Object obj : col) { System.out.println(obj); }
List interface and common methods
The List interface is a sub interface of the Collection interface
- The elements in the List collection class are orderly (i.e. the addition order is consistent with the extraction order) and repeatable
- Each element in the List collection has its corresponding sequential index, that is, it supports index
- The elements in the List container correspond to an integer serial number, which is recorded in the container. The elements in the container can be accessed according to the serial number
- The implementation classes of List interface in JDK API include:
Common are: ArrayList,LinkendList and Vector
List common methods
// The elements in the List collection class are orderly (i.e. the addition order is consistent with the extraction order) and repeatable List list = new ArrayList(); list.add("Zhang San"); list.add("Li Si"); list.add("Wang Wu"); list.add("Zhang San"); System.out.println(list); // Each element in the List collection has its corresponding sequential index, that is, it supports index System.out.println(list.get(0)); //List common methods: // void add (int index,Object ele); Insert ele at index list.add(1,"GUI Liu"); System.out.println(list); // boolean addAll(int index,Collection else); Add all elements in else from the index position List list2 = new ArrayList(); list2.add("Beethoven"); list2.add("Vinci"); list2.add("Einstein");//one more player still needed list.addAll(3, list2); System.out.println(list); // Object get(int index); Returns the element at the specified index location // int indexOf(Object obj); Returns the position where obj first appears in the collection System.out.println(list.indexOf("Zhang San")); // int lastIndexOf(Object obj); Returns the last occurrence of obj in the collection System.out.println(list.lastIndexOf("Zhang San")); // Object remove(int index); Removes the element at the specified index location and returns this element System.out.println(list.remove(list.size()-1)); System.out.println(list); // Object set(int index,Object ele); Setting the element at the specified index position to ele is equivalent to replacing it System.out.println(list.set(list.size()-1, "me")); System.out.println(list); // List subList(int fromIndex,int toIndex); Returns the subset from fromindex to toindex position [fromIndex,toIndex); List returnList = list.subList(3, 7); System.out.println(returnList);
Precautions for ArrayList
- permits all elements,including null, ArrayList can be null, and can be multiple
- ArrayList implements data storage by arrays
- ArrayList is basically equivalent to Vector. Except that ArrayList is thread unsafe (high execution efficiency), ArrayList is not recommended for multithreading
ArrayList underlying structure and source code analysis
-
An array elementData of Object type is maintained in ArrayList
transient Object[] elementData;//transient indicates instantaneous and transient, indicating that the attribute will not be serialized
-
When creating an ArrayList object, if a parameterless constructor is used, the initial elementData capacity is 0. If it is added for the first time, the expanded elementData is 10. If it needs to be expanded again, the expanded elementData is 1.5 times
-
If you use the constructor new ArrayList(int index);, the initial elementDate capacity is the specified size. If you need to expand the capacity, directly expand the elementData to 1.5 times
Look at the source code with DeBug
Vector
Basic introduction
-
Definition description of Vector class
-
The bottom layer of Vector is also an object array, protected Object[] elementData
-
Vector is thread synchronized, that is, it is thread safe. The operation method of vector class is synchronized
public synchronized boolean add(E e) { modCount++; ensureCapacityHelper(elementCount + 1); elementData[elementCount++] = e; return true; }
4. When thread synchronization safety is required in development, consider using Vector
Vector and ArrayList comparison
Bottom structure | edition | Thread safety (synchronization efficiency) | Expansion multiple | |
---|---|---|---|---|
ArrayList | Variable array | jdk1.2 | Unsafe and efficient | If there is a reference structure, 1.5 times. If no parameters 1. The first time 10 2. Expand according to 1.5 from the second time |
Vector | Variable array | jdk1.0 | Safe and inefficient | If there is no parameter, it defaults to 10. When it is full, it will be expanded by twice. If the size is specified with parameters, the capacity will be directly expanded by 2 times each time |
// Vector a little source code List vector = new Vector(); for(int i = 1; i <= 10;i++) { vector.add(i); } vector.add(100); /*1. new Vector(); * public Vector() { this(10);//Call the parameterized construction method, that is, the default Object [] array length is 10 } public Vector(int initialCapacity) { this(initialCapacity, 0); } public Vector(int initialCapacity, int capacityIncrement) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = new Object[initialCapacity]; this.capacityIncrement = capacityIncrement; } 2. vector.add(); public synchronized boolean add(E e) { modCount++;//Number of times the record set was modified ensureCapacityHelper(elementCount + 1);//Call the method to judge whether the expansion is needed and complete the expansion operation elementData[elementCount++] = e; return true; } 2.1 Judge whether capacity expansion is required private void ensureCapacityHelper(int minCapacity) { // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity);//To expand the capacity, call the grow(); method } 2.2 private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity); //Double the original capacity if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); elementData = Arrays.copyOf(elementData, newCapacity);//Capacity expansion } */
LinkedList
LikendList description
- LinkedList bottom layer implements the characteristics of two-way linked list and two terminal queue
- You can add any element (elements can be repeated), including null
- Thread is unsafe and synchronization is not implemented
Underlying operation mechanism of LikendList
- The underlying LinkedList maintains a two-way linked list
- The LinkedList maintains two attributes, first and last, which point to the first node and the last node respectively
- Each Node (Node object) maintains three attributes: prev, next and item. Prev points to the previous Node and next points to the next Node. Finally, a two-way linked list is realized
- Therefore, the addition and deletion of LinkedList elements are not completed through arrays, which is relatively efficient
You can run with DeBug to see the underlying source code
LinkedList linkedList = new LinkedList(); for(int i = 0; i <=10;i++) { linkedList.add(i); } for(int i = 9; i >5;i--) { linkedList.remove(i); } linkedList.set(0, "Zhang San"); System.out.println(linkedList.get(0)); //Followed by the underlying source code and my comments /* constructor * LinkedList linkedList = new LinkedList(); * public LinkedList() { } 2,add(); public boolean add(E e) { linkLast(e);//Walking method return true; } 2.1 void linkLast(E e) { final Node<E> l = last;//Point l to the last list final Node<E> newNode = new Node<>(l, e, null);//new Node(); // Point the prev of newNode forward to the list last = newNode;//List points to the new Node and becomes the current list if (l == null)//Determine whether the previous list is empty first = newNode;//Null, indicating that there are no elements in the previous collection else l.next = newNode;//Point the previous last next to the current last size++; modCount++; } Node(Node<E> prev, E element, Node<E> next) { this.item = element; this.next = next; this.prev = prev; } 3,remove(); public E remove(int index) { checkElementIndex(index);//The following method is mainly used to judge whether the index has > size or < 0; Throw an exception if any return unlink(node(index));// } 3.1 private void checkElementIndex(int index) { if (!isElementIndex(index))//Negate the return value and throw an exception in violation of regulations, otherwise the method will be ended throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } 3.2 Judge whether it is a violation index, and return yes false ,Not return true private boolean isElementIndex(int index) { return index >= 0 && index < size; } 3.3 Node<E> node(int index) { // assert isElementIndex(index); if (index < (size >> 1)) {//Determine whether the to be deleted is in the first half Node<E> x = first;//In, x points to first for (int i = 0; i < index; i++)//for loop from 0 to index x = x.next;//x points to the next (next) of the original x. when looping to < index, it will point to the Node object with index return x;//At the end of the loop, the Node object with index is returned } else { Node<E> x = last;//In the second half, x points to the Node object at the end of the linked list for (int i = size - 1; i > index; i--)//The for loop looks forward from the last index until the index x = x.prev;//X points to the prev of the original x (previous), return x;//The loop ends, and the return result is the same as above } } 3.4 E unlink(Node<E> x) {//At this time, the x object passed in is the object to be deleted // assert x != null; final E element = x.item; //Here for the last return, final Node<E> next = x.next;// Next points to x.next (next) final Node<E> prev = x.prev;// Prev points to x.prev (previous) if (prev == null) {//If prev is null, if so, it indicates that it is the first one deleted first = next;//Point first to next } else {//Not null, description is not the first prev.next = next;//The next before x points to the next after X x.prev = null;//prev of x is null } if (next == null) {//Judge whether the next is null. If so, it indicates that the deleted is the last one last = prev;//Point to the last last last point to the previous x } else { next.prev = prev;//Not null, prev after x points to the previous one of x x.next = null;//Finally, set the next of x to null } x.item = null;//Finally, set the item of x to null, no reference points to it, and it does not point to any. It is helpless size--;//x is alone, that is, the deletion number, size-- modCount++; return element;//return } 4,set(); public E set(int index, E element) { checkElementIndex(index);//Using this method with remove is the same as determining whether the index is a violation index and whether an exception needs to be thrown Node<E> x = node(index);//Go to node(index); Return the Node corresponding to index to x E oldVal = x.item;//Give the original data item of x to oldVal to return the value x.item = element;//Replace the data of x with the parameter element return oldVal;//return } 5,get(); public E get(int index) { checkElementIndex(index);//The same as remove and set. It is used to judge whether the index is a violation index and whether an exception needs to be thrown return node(index).item;//node(index) returns the corresponding object of index and directly takes out the data item to return }
ArrayList and LinkedList comparison
Bottom structure | Efficiency of addition and deletion | Efficiency of modification | |
---|---|---|---|
ArrayList | Variable array | Lower (array expansion) | higher |
LinkedList | Bidirectional linked list | High, append through linked list | Lower |
How to select ArrayList and LinkedList
- If we have many operations to change, select ArrayList
- If we add and delete many operations, select LinkedList
- Generally speaking, in the program, 80% ~ 90% are queries, so ArrayList will be selected in most cases
- In a project, it can be selected flexibly according to the business. The night song module uses ArrayList and the other module is LinkedList, that is, it should be selected according to the business