Detailed parsing of java containers

Source: Internet
Author: User
Tags addall

Detailed parsing of java containers

In java development, we will certainly use a large number of collections. Here I will summarize the common collection classes, the advantages and disadvantages of each collection class, so that we can better use the set. Below I will use a picture to represent

The light green indicates the interface, while the red indicates the class we often use.

1: Basic Concepts

Java container class libraries are used to save objects. They can be divided into two concepts.

1.1: Collection

A sequence of independent elements that follow one or more rules. The List must store elements in the inserted order, the Set cannot have repeated elements, and the Queue determines the order in which objects are generated based on queuing rules (usually the same as the insertion order)

1.2: Map

A value key pair object that forms a pair. You can use a key to search for a value. ArrayList allows us to use numbers to search for values. It associates numbers with objects. While Map allows us to use an object to find an object, which is also called an associated array. Or a dictionary.

2: List

List promises to maintain elements in a specific sequence. The List interface adds a large number of methods to the Collection, allowing you to insert and remove elements in the List. The following describes two types of List

2.1: Basic ArrayList

It has the advantage that random access to elements is fast, but insertion and removal in the middle is slow.

Now let's take a look at why the random access to ArrayList is faster, while insertion and removal are slower. First, let's talk about ArrayList initialization.

ArrayList can be initialized in three ways:

private transient Object[] elementData;
public ArrayList() {        this(10);    }  public ArrayList(int initialCapacity) {        super();        if (initialCapacity < 0)            throw new IllegalArgumentException("Illegal Capacity: "+                                               initialCapacity);        this.elementData = new Object[initialCapacity];    } public ArrayList(Collection<? extends E> c) {        elementData = c.toArray();        size = elementData.length;        // c.toArray might (incorrectly) not return Object[] (see 6260652)        if (elementData.getClass() != Object[].class)            elementData = Arrays.copyOf(elementData, size, Object[].class);    }

We can see that ArrayList actually uses an array (by default, an array with a length of 10 ). All arraylists have the same efficiency as arrays when reading data, and their time complexity is 1.

The end of the insert operation is elementData [size ++] = e. Of course, it will be resized in the middle. Why is it relatively slow to insert an intermediate source code?

Public void add (int index, E element) {rangeCheckForAdd (index); // verify (optional) ensureCapacityInternal (size + 1); // Increments modCount !! (Resize beyond the current array length) System. arraycopy (elementData, index, elementData, index + 1, size-index); (core code) elementData [index] = element; size ++ ;}

System. arraycopy (elementData, index, elementData, index + 1) the first parameter is the source array, the starting position of the source array, the target array, the starting position of the target array, and the number of elements copied to the array. This means that each element moves one digit backward from the index, then the index is left blank, and the element is assigned to it. In this way, we do not know where to insert the data, so we will perform the matching, so its time assignment degree is n.

2.2: Upload list

It inserts and removes the List at a lower cost, providing optimized sequential access, but it is relatively slow in random access. However, its features are much more powerful than ArrayList. Support for Queue and Stack

ListedList uses chained storage. Chained storage determines a Node. It includes three parts: the frontend node, the successor node, and the data value. Therefore, his physical address is not necessarily continuous during storage.

Let's take a look at its intermediate insertion implementation.

From the code, we can see that we first obtain the precursor node of the index element, then use this element as the successor node, and then create a new node. The new node precursor node is the same as the obtained precursor node, the successor node is equal to the element to be moved. So there is no need to loop here, so it is more efficient to insert and delete.

Let's take a look at the query (we can find that its efficiency is much lower than that of ArrayList)

3: Set

Set is also a Set, but it is characteristic that there can be no repeated objects. Therefore, Set is most commonly used to test the property normalization, and it is easy to ask whether an object exists in the Set. In addition, Set has the same interface as Collection, and does not have any additional functions, but it only shows different behaviors.

3.1: HashSet

The query speed of HashSet is relatively fast, but the stored elements are random and not sorted. Let's write a program to see it.

Public static void main (String [] args) {/*** there is no sequence to follow, because hashset uses hash columns (for Speed considerations) */Random random = new Random (47); Set <Integer> intset = new HashSet <Integer> (); for (int I = 0; I <10000; I ++) {intset. add (random. nextInt (30);} System. out. print (intset );}

3.2: TreeSet

TreeSet stores elements in the red-black tree structure, so the stored results are ordered (so select TreeSet if you want to store the set in sequence)

public static void main(String[] args){        Random random=new Random(47);        Set<Integer> intset=new TreeSet<Integer>();        for (int i=0;i<10000;i++){            intset.add(random.nextInt(30));        }        System.out.print(intset);    }

Let's talk about LinkedHashSet later.

4: Queue

Queue is a Queue. A Queue is a typical first-in-first-out container. It is used to place elements from one end of the container and extract elements from the other end. The order of elements in the container is the same as that in the container. The Queue list provides the implementation of the Queue, and the Queue list is transformed to the Queue. Among them, Queue includes offer, peek, element, pool, remove, and other methods.

Offer inserts an element into the end of the team. If false is returned, the addition fails. Both peek and element will return the first pair without being removed, but peek returns null when the first is null, and element will throw the NoSuchElementException exception. The poll and remove methods will be removed and return the opposite, but poll is null in the queue, while remove will throw NoSuchElementException exception. The following is an example

  public static void main(String[] args){        Queue<Integer> queue=new LinkedList<Integer>();        Random rand=new Random();        for (int i=0;i<10;i++){            queue.offer(rand.nextInt(i+10));        }        printQ(queue);        Queue<Character> qc=new LinkedList<Character>();        for (char c:"HelloWorld".toCharArray()){            qc.offer(c);        }        System.out.println(qc.peek());        printQ(qc);        List<String> mystrings=new LinkedList<String>();        mystrings.add("1");        mystrings.get(0);        Set<String> a=new HashSet<String>();        Set<String> set=new HashSet<String>();        set.add("1");    }    public static void printQ(Queue queue){        while (queue.peek

From the above output results, we can see that the results are not in an order and there are no rules. If you want the queue to output the results according to the rules, we should consider the priority at this time, in this case, we should use PriorityQueue. If we call the offer method to insert an object, this object will be sorted by priority in the column, the default situation is natural sorting. Of course, we can use Comparator to modify this order (in the next article ). PriorityQueue can ensure that when you call the peek, pool, and remove methods, the obtained elements will be the highest priority element in the column. OK. We can view the code again.

 public static void main(String[] args) {        PriorityQueue<Integer> priorityQueue = new PriorityQueue<Integer>();        Random rand = new Random();        for (int i = 0; i < 10; i++) {            priorityQueue.offer(rand.nextInt(i + 10));        }        QueueDemo.printQ(priorityQueue);        List<Integer>ints= Arrays.asList(25,22,20,18,14,9,3,1,1,2,3,9,14,18,21,23,25);        priorityQueue=new PriorityQueue<Integer>(ints);        QueueDemo.printQ(priorityQueue);    }

From the output, we can see that repetition is allowed, and the minimum value has the highest priority (if it is String, spaces can also be counted as values, and have a higher priority than letters). If you want to eliminate duplication, you can use Set for storage and use Set as the initial value of the priorityQueue object.

5: Map

Map is widely used in actual development, especially HashMap. Imagine that we want to save the values of some elements in an object. If we create an object, it will be a little troublesome, at this time, we can use map. HashMap uses hash functions, so the query efficiency is relatively high. If we need an ordered function, we can consider using TreeMap. Here we will mainly introduce the HashMap method. Note that the key of HashMap can be null, and the key value cannot be repeated. If it is repeated, the first key value will be overwritten.

Put adds a value key pair, including containsKey verification, containsValue verification, keySet, values, and entrySet.

Public static void main (String [] args) {// Map <String, String> pets = new HashMap <String, String> (); Map <String, string> pets = new TreeMap <String, String> (); pets. put ("1", "Zhang San"); pets. put ("2", "Li Si"); pets. put ("3", "Wang Wu"); if (pets. containsKey ("1") {System. out. println ("Key 1 already exists");} if (pets. containsValue ("James") {System. out. println ("three values already exist");} Set <String> sets = pets. keySet (); Set <Map. entry <String, String> entrySet = pets. entrySet (); Collection <String> values = pets. values (); for (String value: values) {System. out. println (value + ";") ;}for (String key: sets) {System. out. print (key + ";") ;}for (Map. entry entry: entrySet) {System. out. println ("key:" + entry. getKey (); System. out. println ("value:" + entry. getValue ());}}

6: Iterator and Foreach

Now the foreach syntax mainly applies to arrays, but it can also be applied to all Collection objects. Collection can use foreach because it inherits the Iterator interface. Below I will write a code segment for you to view

public class IteratorClass {    public Iterator<String> iterator(){      return new Itr();    }    private class Itr implements Iterator<String>{        protected String[] words=("Hello Java").split(" ");        private int index=0;        public boolean hasNext() {            return index<words.length;        }        public String next() {            return words[index++];        }        public void remove() {        }    }}
 Iterator iterators=new IteratorClass().iterator();        for (Iterator it=iterator;iterators.hasNext();) {            System.out.println(iterators.next());        }        while (iterators.hasNext()){            System.out.println(iterators.next());        }

From this we can see that the foreach loop is eventually converted to for (Iterator it = iterator; iterators. hasNext ();), but jdk helps us hide it and we cannot view it. Next we will analyze a question about List deletion. Most of us must have used the for loop or foreach loop to delete the objects, but the results are obvious and there will be errors, so now let's analyze why there will be errors.

1: Use the for loop to delete (error analysis is displayed)

2: foreach loop deletion (Error Analysis)

We learned from the above that foreach will eventually be converted into an Iterator, so it will first get the element through next. Let's look at the code.

Please refer to the for loop to delete that section of code. If modCount is not deleted once, it will be ++. Therefore, the modCount cannot be deleted because of the increase in modCount and expectedModCount during the second deletion.

3: The correct deletion method

The code using the iterator is as follows:

 Iterator<String> iterator=userList.iterator();        while (iterator.hasNext()){            iterator.next();            iterator.remove();        }

Please remember to add iterator. next (); this is because there is a lastRed in the source code, which records whether it is the last element, if the iterator is not added. next (), lastRed =-1. When the verification is deleted, if (lastRet <0) throw new IllegalStateException () is returned.

 

7: Collections and Arrays

Here we will only introduce two common Collections. addAll and Arrays. asList

AddAll:

AsList uses arrays.

It can be seen that the final conversion is to ArrayList.

8. Summary

1): An array is used to associate numbers with objects. It stores clear objects and does not need to convert the query results when querying objects. It can be multidimensional, you can save data of the basic type, but once an array is generated, its capacity cannot be changed. Therefore, you cannot directly delete or add elements to arrays.

2): Collection stores a single element, while Map stores the associated value-key pairs. With Java generics, you can specify the type of objects to be stored in the container, objects of the error type are not placed in the container, and no transformation is required when elements are retrieved. In addition, both Collection and Map can automatically adjust their sizes. The container cannot hold the basic type.

3): Like arrays, lists also establish associations between numbers and objects. Therefore, arrays and lists are sorted containers, and lists can be automatically resized.

4): if a large number of random accesses are required, ArrayList should be used. If you want to insert and delete data from the center frequently, the history list should be used.

5): Various Queue and Stack are supported by Queue list

6): Map is a design that associates objects (rather than numbers) with objects. HashMap is used for fast access. TreeMap keeps keys in the sorting state, so it is not as fast as HashMap. HashMap keeps the element insertion order, but also provides fast access through hash.

7): The Set does not accept repeated elements. The HashSet provides the fastest access capability. The TreeSet keeps the elements in order, and the sorted HashSet stores the elements in insert sequence.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.