Java Core Technology Carding-Collection

Keywords: Java Lambda JQuery less

I. Preface

In daily development, we often encounter the need to know the number of objects at runtime. This situation can not use arrays, because arrays are a fixed number, we will use collections at this time, because collections can store an indefinite number of objects.

Collection classes are particularly useful tool classes. They can store not only different numbers of objects, but also common data structures, and associative arrays with mapping associations.

Collection classes and arrays are different. Data can store both basic types and objects, while collections can only store objects (object reference variables).

Java collections are roughly divided into:

  • Set: Unordered, non-repeatable sets

  • List: Ordered, repeatable sets

  • Map: Set of mapping relationships

  • Queue: Queue collection

Java collection classes are mainly derived from two interfaces: Collection and Map.

The framework of the set can be seen in this diagram: http://img.blog.csdn.net/20160124221843905

Collection and Iterator

2.1 Collection

Collection interface is the parent interface of List, Set and Queue. It defines some general methods of collection operation. Collection is similar to a container, but container is nothing more than adding objects, deleting objects, emptying containers, and judging whether the container is empty.

Collection collection = new ArrayList();
//Add to
collection.add("Good night");
collection.add(9);
//Return length
System.out.println(collection.size());
//remove
collection.remove(9);
//Does it contain
System.out.println(collection.contains("Good night"));
//Is it empty?
System.out.println(collection.isEmpty());
Collection books = new HashSet();
books.add("Good night");
books.add("May the night be long without dreams");
books.add("Sleep all night");
//Remove collection Included elements
books.removeAll(collection);
System.out.println(books);
books.add("Good night");
//Keep both data
books.retainAll(collection);
System.out.println(books);

Collection inherits the Iterable interface, Java 8 provides the forEast method for Iterable, and the parameter of this method is a functional interface through which we can traverse the collection and use Lambda expressions.

books.forEach(p -> System.out.println(p));

2.2 Iterator

//Obtain iterators
Iterator iterator = books.iterator();
//Determine whether traversal is complete
while (iterator.hasNext()){
    //Gets the next element in the collection, and returns Object Object, which requires mandatory conversion
    String text = (String)iterator.next();
    System.out.println(text);
    //The deleted object here is deleted in the iterator, and the last one is deleted. next Method returned, and not really deleted books Content in
    iterator.remove();
    //Report wrong
    books.remove(text);
}

We can see that there is a deletion method here, but it is not the contents of books that are deleted, and if we modify the contents, the actual contents will not change. Here we can conclude that the collection does not pass itself to the iterator, but the elements in the collection to the iterator.

Iterators adopt a fast failure mechanism. Once the set is changed during the iteration, errors are thrown immediately, which can avoid sharing resources and lead to data inconsistency.

We can also traverse directly through forEachRemaining, which is also a functional interface.

iterator.forEachRemaining(p-> System.out.println(p));

2.3 foreach

In addition to iterators, we can traverse collections directly through foreach, which is more convenient to write.

for (Object s : books) {
    System.out.println(s);
}

Like iterators, the loop here is not the set itself, but the elements, and cannot be modified.

2.4 Predicate

Java 8 provides a removeIf (Predicate <? Super E > filter) method for Collection. This method is to delete qualified elements in batches. It is also a functional interface. We can use Lambda expressions.

books.removeIf(p -> ((String) p).length() > 5);

This Predicate can be fully utilized to simplify set operations, such as:

public static int count(Predicate predicate, Collection collection) {
    int total = 0;
    for (Object object : collection) {
        //Judging whether conditions are met
        if (predicate.test(object)) {
            total++;
        }
    }
    return total;
}
System.out.println(count(p -> ((String) p).length() > 5, books));

2.4 Stream

Collection also has a Stream() streaming API, which is often used in JQuery. It is mainly divided into intermediate method and terminal method. As the name implies, intermediate method is allowed to continue to call subsequent methods, while terminal method is the final operation. The introduction of Stream greatly enriches the operation of collections.

Commonly used intermediate methods are

  • Filter (Predicate <? Super T > predicate): Filtering unconditional sets

  • sorted: sort

  • limit(long maxSize): Control of quantities, usually after sorting

  • distinct(): weight removal

Commonly used end-to-end methods are

  • ForEach (Consumer <? Super T > action): traversal

  • toArray(): Converting data

  • Min (Comparator <? Super T > comparator): Get the minimum

  • Max (Comparator <? Super T > comparator): Get the maximum

  • count(): total

We can easily combine these API s and operate on collections. A simple example is as follows:

System.out.println(books.stream().filter(p->((String) p).contains("night")).count());

In peacetime development, we can gradually become familiar with these writing methods.

Three, Set

Set does not remember the order of addition, that is, it will not be sorted according to the order of addition, and it does not allow duplicate elements to be included. When duplicate elements are added, the add method returns false. The implementation classes HashSet, TreeSet, LinkedHashSet, EnumSet are described below.

3.1 HashSet

As the name implies, HashSet stores elements in a collection according to the Hash algorithm, so it has good storage and search performance. HashSet is not thread-safe. In multi-threaded cases, we need code to ensure its synchronization. HashSet element value can be null.

HashSet determines whether two objects are identical by judging that equals() is equal and hashCode() returns the same value.

Then there will be some problems.

  1. If the equals() of the two objects is true, but hashCode() returns different values, then HashSet thinks that these two objects are different and will be saved, but in fact they are different from our expectations.

  2. If the hashCode() return value of the two objects is equal, but equals() is false, it will be saved at this time, but it will be saved in the same place and stored through the chain structure, which will have an impact on performance.

So if we want to save the object in HashSet, we should try to ensure that when equals() is true, the return hashCode() value of the two objects is equal.

3.2 LinkedHashSet

LinkedHashSet is a subclass of HashSet, and LinkedHashSet is located by hashCode, but as you can see from its name, it also maintains insertion order through a linked list, which means that it can be ordered during traversal, but adding sorting means performance degradation.

3.2 TreeSet

TreeSet is the implementation class of SortedSet, which means that TreeSet can ensure that the collection elements are sorted. Since sorting is needed, there are sorting rules. TreeSet has two sorting methods: natural sorting and custom sorting.

  • Natural Sorting: TreeSet calls the compareTo method to compare the sizes between elements.

  • Custom Sorting: Custom Sorting is that we sort according to the rules we make.

TreeSet treeSet=new TreeSet((o1,o2)->
{
   String m1 = (String)o1;
   String m2=(String)o2;
   return m1.length()>m2.length()?-1:0;
});

Because you want to sort, TreeSet must add the same class element, otherwise it will report an error.

Because sorting has been added, some methods have been added accordingly:

TreeSet<Integer> treeSet1 = new TreeSet<>();
treeSet1.add(1);
treeSet1.add(2);
treeSet1.add(3);
//A previous element
System.out.println(treeSet1.lower(2));
//The latter element
System.out.println(treeSet1.higher(2));
//First element
System.out.println(treeSet1.first());
//Last element
System.out.println(treeSet1.last());

3.4 EnumSet

EnumSet is a collection that stores enumerations specifically. All elements must be enumerated values of the specified enumeration type. EnumSet is also ordered, with the same sort order as the enumeration definition.

EnumSet is stored internally in the form of bit vectors, which is very compact, efficient and efficient. EnumSet does not allow null.

3.5 Performance Selection

How to choose HashSet and TreeSet? In terms of performance, HashSet is better, because TreeSet requires additional red-black tree algorithm to sort, so if we don't need to sort, we all choose HashSet.

Four, List

List is an ordered, repeatable set, each element can be accessed through the corresponding index. List inherits Collection, and the method List in Collection can be used. As an ordered set, List also has some index-related methods.

List list = new ArrayList();
list.add("Good night");
list.add("Wish you a long way to go");
list.add("Somebody's around.");
list.forEach(p-> System.out.println(p));
list.remove(1);
//Add data to the index
list.add(1, "Wish you a long way to go");
//Gets the specified index location element
System.out.println(list.get(2));
System.out.println(list.size());
//Data for setting index position,index Must be within the existing length
list.set(2, "I haven't finished what I want to say yet.");
//Return fromIndex(Contain),reach toIndex(Not Including) Sets to New Sets
List list1 = list.subList(0, 2);
//Sort, compare function
list.sort((o1, o2) -> ((String) o1).length() - ((String) o2).length());
//Replace the original set with string length as a new set element
list.replaceAll(p -> ((String) p).length());
list.forEach(p-> System.out.println(p));

4.1 ArrayList ,Vector,LinkedList

ArrayList, Vector and LinkedList are three implementation classes of list, which fully support all the functions implemented by the previous list interface.

ArrayList and Vector are based on arrays, which encapsulate a dynamic and redistributive Object [] array. Initialization is to determine the initial length through the initial Capacity parameter. If not specified, the default is 10. When we can determine the length of the array, we can give it. This can reduce the number of redistributions and improve performance.

ArrayList and Vector are exactly the same in use, but Vector appeared earlier, some of them have longer names, and then changed to List interface, adding some methods, but there are some repetitions with the previous methods, we generally like to use new things, although Vector thread is safe, but if we use Collections tool class, we can also make Array. List threads are safe, so the summary is to use ArrayList.

LinkedList's internal implementation is totally different from ArrayList and Vector's. Its internal implementation is stored by linked list, and it also inherits Deque interface, that is, it can be used as a double-ended queue, which shows its powerful function.

LinkedList<String> linkedList = new LinkedList();
//Put the string at the end of the queue
linkedList.offer("Queue tail string");
//Place characters at the top of the stack
linkedList.push("String at the top of stack");
//Place strings at the head of the queue
linkedList.offerFirst("Queue Header String");
linkedList.forEach(p-> System.out.println(p));
//Access does not delete stack top elements
System.out.println(linkedList.peekFirst());
//Access does not delete the last element of the queue
System.out.println(linkedList.peekLast());
//Pop-up stack top element
System.out.println(linkedList.pop());
//Access and delete the last element of the queue
System.out.println(linkedList.pollLast());

Five, Queue

Queue is used to simulate the data structure of queues, i.e. first-in-first-out containers. Queues are simply understood as queues for cooking. The first person in the queue eats first, and then goes to the end of the queue. Queues usually do not allow random access to data (which is equivalent to queue jumping). There are the following methods: add (E)

  • Add (E): Add elements to the tail.

  • Offer (E): It also adds elements to the tail, but it is more efficient than add when using queues with limited capacity.

  • remove(): Get the header element and delete it.

  • poll(): Get the tail element and delete it.

  • element(): Gets the header element, but does not delete it.

  • peek(): Gets the header element, but does not delete it. The queue is empty and returns null

Queue interface has PriorityQueue implementation class. In addition, Queue has a Deque sub-interface, which is a double-ended queue. It can add and delete elements from both sides, so that Deque implementation class can be used as a queue or a stack. The LinkedList above is its implementation subclass, and there is also an ArrayDeque.

5.1 PriorityQueue

PriorityQueue is not a standard queue, because it saves the order of queues not in the order of additions, but in the order of sizes, which violates the basic principle of queues: first in, first out, and the rules of sorting are the same as TreeSet, so I won't repeat them here.

5.2 ArrayDeque

ArrayDeque implements Deque, that is to say, it is a two-end queue. Simply understood is that it can be used both as a queue and as a stack. When we need the data structure of the stack, we recommend using ArrayDeque. Stack is an ancient collection and is not recommended.

We use Array Deque as stack and queue respectively:

Stack:

ArrayDeque<String> stack = new ArrayDeque();
stack.push("Good night");
stack.push("Wish you a long way to go");
stack.push("Somebody's around.");
System.out.println(stack);
//Access the first element, but do not pop up
System.out.println(stack.peek());
//Access the first element and pop up
System.out.println(stack.pop());
System.out.println(stack);

Queue:

ArrayDeque<String> queue=new ArrayDeque<>();
queue.offer("Good night");
queue.offer("May the night be long without dreams");
queue.offer("Sleep every night");
System.out.println(queue);
//Access the queue header element, but do not delete it
System.out.println(queue.peek());
//Access the queue header element and delete it
System.out.println(queue.poll());
System.out.println(queue);

Six, Map

Map is used to store data with mapping relationship, that is, key-value pairs. Map sets store two sets of values, one set of key and the other set of value. These two sets of data can be data of any application type. Key does not allow duplication, and key and value have one-to-one relationship in one direction.

The keys in a Map are combined into a Set set. The keys are not sequential or repeatable. A keySet() method in a Map is to get a Set of keys.

Some common methods of Map are as follows:

HashMap<Integer, String> map = new HashMap<>();
//Put data in
map.put(1,"Song Jiang");
map.put(2,"Lu Jun Yi");
map.put(3,"Wu Yong");
//If there is data in the original location, the original data will be returned.
System.out.println(map.put(3,"Wu Song"));
//Whether there exists a ____________ key
System.out.println(map.containsKey(2));
//Whether there exists a ____________ value
System.out.println(map.containsValue("Wu Song"));
//Is it empty?
System.out.println(map.isEmpty());
//Get length
System.out.println(map.size());
//loop key value
for (Object key: map.keySet()) {
    //adopt key Direct acquisition of values value
    System.out.println(map.get(key));
}
//according to key Removing Elements
System.out.println(map.remove(3));
//New cycle
map.forEach((key,value)-> System.out.println(key+":"+value));
//Obtain value,Returns default value if nonexistent
map.getOrDefault(8,"There is no such person.");
//It's just a replacement, not a new addition.
map.replace(2,"Lin Chong");
//wipe data
map.clear();

6.1 HashMap and Hashtable

HashMap and Hashtable are typical implementation classes of Map interface. They are similar to ArrayList and Vector. Hashtable appears early and thread-safe, but implementation is not good. HashMap has better performance but thread-unsafe. HashMap's key and value are not allowed to be empty, but HashMap can be used. We generally recommend HashMap. Collections can be used even if thread-safe is required. Tool class.

If we want to store key correctly, we must let the object as key implement hashCode() and equals() methods. Then we can judge whether the two keys are equal or not, which is the same as HashSet. We must have hashCode() equal and equals() return to true.

In addition to the key value, we sometimes have to compare whether the value value is equal to containsValue(), so we only need to return equals() to true.

6.2 LinkedHashMap

HashMap also has a subclass LinkedHashMap, which uses a two-way linked list to maintain the order of key-value, and a linked list to maintain the order of iteration, which is the same as the order of insertion. LinkedHashMap needs to maintain the insertion order of elements, which is less efficient than HashMap, but because it maintains the order, iteration time is faster.

6.3 TreeMap

TreeMap is a red-black tree data structure. Each key-value is a node of the red-black tree. When stored, the nodes are sorted according to the key. TreeMap guarantees that the key-value is in an ordered state. It is also two sorting mechanisms. Natural sorting and customized sorting are similar to the previous ones.

Because TreeMap is orderly, it will provide some access to the previous, the latter, the first and the last method. Specific methods refer to API documents.

6.4 WeakHashMap

As you can see from the name, WeakHashMap is a weak reference object. HashMap's key retains a strong reference to the object, which means that as long as the HashMap object is not destroyed, the object referenced by HashMap will not be destroyed. HashMap will not automatically delete the key-value corresponding to these keys, but WeakHashMap will not.

6.5 EnumMap

EnumMap is used with enumeration classes. That is to say, the key of each EnumMap must be an enumeration value. When creating EnumMap, it must show or implicitly specify the corresponding enumeration classes. EnumMap is stored in an array form internally, compact and efficient, and sorted in the order defined by the enumeration class. The key is not allowed to be null, but the value is null.

Collections Tool Class

Collections tool class has been mentioned above, that is, the tool class used to manipulate the collection, the operation of the collection has sorting, search, synchronization control, set immutable.

7.1 ranking

Collections provides the following method for sorting list s

ArrayList<Integer> list = new ArrayList<>();
list.add(2);
list.add(8);
list.add(5);
list.add(10);
list.add(7);
System.out.println("----Natural ordering----");
//Natural ordering
Collections.sort(list);
list.forEach(p-> System.out.println(p));
System.out.println("----Reversal----");
//Reversal
Collections.reverse(list);
list.forEach(p-> System.out.println(p));
System.out.println("----Stochastic ranking----");
//Random sorting, equivalent to shuffling
Collections.shuffle(list);
list.forEach(p-> System.out.println(p));
System.out.println("----Customized Sorting Rules----");
//Customized Sorting Rules
Collections.sort(list,(o1,o2)->(o1-o2));
list.forEach(p-> System.out.println(p));
System.out.println("----Customized Sorting Rules----");
//Exchange list The order of specified positions in
Collections.swap(list,2,4);
list.forEach(p-> System.out.println(p));
System.out.println("----take list Move the last two elements to the front----");
//take list Move the last two elements to the front
Collections.rotate(list,2);
list.forEach(p-> System.out.println(p));
System.out.println("----take list Move the last two elements to the front----");
//take list Move the first two elements to the back
Collections.rotate(list,-2);
list.forEach(p-> System.out.println(p));

7.2 Find and Replace Operations

Collections provides the following methods for finding and replacing list s

ArrayList<Integer> list = new ArrayList<>();
list.add(2);
list.add(8);
list.add(5);
list.add(10);
list.add(7);
list.add(7);
//Natural ordering
Collections.sort(list);
//binary search list,The parameters introduced are value,Returns the index value (must be sorted)
System.out.println(Collections.binarySearch(list,10));
//Maximum value
System.out.println(Collections.max(list));
//minimum value
System.out.println(Collections.min(list));
//Number of occurrences
System.out.println(Collections.frequency(list,8));
//New values replace all old values
Collections.replaceAll(list,8,6);
list.forEach(p-> System.out.println(p));
//replace all
Collections.fill(list,8);

7.3 Synchronization Control

As mentioned above, Collections can be used many times to turn Collections into thread-safe, so long as synchronized XXX () is invoked, threaded Collections can be created.

Such as:

Collection<Object> objects = Collections.synchronizedCollection(new ArrayList<>());

7.4 Invariant Sets

Collections provides three kinds of methods to obtain immutable sets

  • emptyXXX(): Returns an immutable, empty collection object

  • Singleton XXX (): Returns an immutable collection containing only one object

  • Unmodifiable XXX (): Returns an invariant view of the specified collection

Collections.emptyList();
Collections.singletonList("I see");
ArrayList<Integer> list = new ArrayList<>();
Collections.unmodifiableCollection(list);

This is the introduction of collections and the basic usage, of course, this is only for use, and the source code analysis will be done later.

Posted by Matt Phelps on Thu, 25 Apr 2019 14:03:35 -0700