java learning notes - Set - List

Collection introduction

Insufficient array

  1. The length must be specified at the beginning and cannot be changed once specified
  2. Saved elements must be of the same type
  3. Using arrays to add elements is troublesome

aggregate

  1. You can dynamically save any number of objects

  2. 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>
  1. Collection implementation subclass can store multiple elements, and each element can be an Object
  2. Some Collection implementation classes can store duplicate elements, while others cannot
  3. Some Collection implementation classes, some are ordered (List), and some are not ordered (Set)
  4. 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

  1. The Iterator object is called an Iterator and is mainly used to traverse the elements in the Collection
  2. 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
  3. 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

  1. The elements in the List collection class are orderly (i.e. the addition order is consistent with the extraction order) and repeatable
  2. Each element in the List collection has its corresponding sequential index, that is, it supports index
  3. 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
  4. 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

  1. permits all elements,including null, ArrayList can be null, and can be multiple
  2. ArrayList implements data storage by arrays
  3. 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

  1. 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

  2. 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

  3. 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

  1. Definition description of Vector class

  2. The bottom layer of Vector is also an object array, protected Object[] elementData

  3. 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 structureeditionThread safety (synchronization efficiency)Expansion multiple
ArrayListVariable arrayjdk1.2Unsafe and efficientIf 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
VectorVariable arrayjdk1.0Safe and inefficientIf 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

  1. LinkedList bottom layer implements the characteristics of two-way linked list and two terminal queue
  2. You can add any element (elements can be repeated), including null
  3. Thread is unsafe and synchronization is not implemented

Underlying operation mechanism of LikendList

  1. The underlying LinkedList maintains a two-way linked list
  2. The LinkedList maintains two attributes, first and last, which point to the first node and the last node respectively
  3. 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
  4. 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 structureEfficiency of addition and deletionEfficiency of modification
ArrayListVariable arrayLower (array expansion)higher
LinkedListBidirectional linked listHigh, append through linked listLower

How to select ArrayList and LinkedList

  1. If we have many operations to change, select ArrayList
  2. If we add and delete many operations, select LinkedList
  3. Generally speaking, in the program, 80% ~ 90% are queries, so ArrayList will be selected in most cases
  4. 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

Tags: Java

Posted on Mon, 29 Nov 2021 12:45:45 -0500 by pluto