Home  >  Article  >  Java  >  What is a collection class in Java? Explanation of collection class structure with graphic examples

What is a collection class in Java? Explanation of collection class structure with graphic examples

伊谢尔伦
伊谢尔伦Original
2017-05-30 11:29:382864browse

1. Collections in Java

Collection classes in Java are the most frequently used and convenient classes in Java programming. As a container class, the collection class can store any type of data. Of course, it can also be combined with generics to store specified types (but generics are only valid at compile time and will be erased at runtime). What is stored in the collection class is only a reference to the object, not the object itself. The capacity of the collection class can be dynamically expanded during runtime, and it also provides many convenient methods, such as finding the union and intersection of sets.

2. Collection class structure

Sets in Java contain a variety of data structures, such as linked lists, queues, Hash table etc. From the perspective of class inheritance structure, it can be divided into two major categories. One is inherited from the Collection interface. This type of collection includes collection classes such as List, Set, and Queue. The other type is inherited from the Map interface, which mainly includes collection classes related to hash tables. Let's take a look at the inheritance structure diagram of these two categories:

1, List, Set and Queue

##The green dotted line in the figure represents the implementation, the green solid line represents the inheritance between interfaces, and the blue solid line represents the inheritance between classes.

  (1) List: We use more Lists including ArrayList and LinkedList. The difference between the two is also obvious, which can be seen from their names. The bottom layer of ArrayList is implemented through arrays, so its random access speed is relatively fast, but for situations that require frequent additions and deletions, the efficiency is relatively low. For LinkedList, the bottom layer is implemented through a linked list, so addition and deletion operations are easier to complete, but the efficiency of random access is relatively low.


Let’s first look at the insertion efficiency of the two:

package com.paddx.test.collection;
import java.util.ArrayList;
import java.util.LinkedList;
public class ListTest {
public static void main(String[] args) {
for(int i=;i<;i++){
}
long start = System.currentTimeMillis();
LinkedList<Integer> linkedList = new LinkedList<Integer>();
for(int i=;i<;i++){
linkedList.add(,i);
}
long end = System.currentTimeMillis();
System.out.println(end - start);
ArrayList<Integer> arrayList = new ArrayList<Integer>();
for(int i=;i<;i++){
arrayList.add(,i);
}
System.out.println(System.currentTimeMillis() - end);
}
}

The following is the result of local execution:

23

1227

It can be seen that in this case, the insertion efficiency of LinkedList is much higher than that of ArrayList. Of course, this is a relatively extreme situation. Let’s compare the efficiency of random access between the two:

package com.paddx.test.collection;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Random;
public class ListTest {
public static void main(String[] args) {
Random random = new Random();
for(int i=;i<;i++){
}
LinkedList<Integer> linkedList = new LinkedList<Integer>();
for(int i=;i<;i++){
linkedList.add(i);
}
ArrayList<Integer> arrayList = new ArrayList<Integer>();
for(int i=;i<;i++){
arrayList.add(i);
}
long start = System.currentTimeMillis();
for(int i=;i<;i++){
int j = random.nextInt(i+);
int k = linkedList.get(j);
}
long end = System.currentTimeMillis();
System.out.println(end - start);
for(int i=;i<;i++){
int j = random.nextInt(i+);
int k = arrayList.get(j);
}
System.out.println(System.currentTimeMillis() - end);
}
}

The following is the result of my local execution:

5277

6

It is obvious that the random access efficiency of ArrayList is several orders of magnitude higher than that of LinkedList. Through these two pieces of code, we should be able to clearly understand the differences between LinkedList and ArrayList and the applicable scenarios. As for Vector, it is a thread-safe version of ArrayList, while Stack corresponds to the stack data structure. These two are rarely used, so I will not give an example here.


 (2)Queue: Generally, it can be completed directly using LinkedList. As can be seen from the above class diagram, LinkedList inherits from Deque, so LinkedList has the function of a double-ended queue. The characteristic of PriorityQueue is to provide a priority for each element, and elements with high priority will be dequeued first.


 (3)Set: The main difference between Set and List is that Set does not allow elements to be repeated, while List allows elements to be repeated. Determining the duplication of elements needs to be determined based on the hash method and equals method of the object. This is why we usually override the hashCode method and equals method for the element classes in the collection. Let’s take an example to look at the difference between Set and List, as well as the functions of hashcode method and equals method:

package com.paddx.test.collection;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
public class SetTest {
public static void main(String[] args) {
Person p1 = new Person("lxp",10);
Person p2 = new Person("lxp",10);
Person p3 = new Person("lxp",20);
ArrayList<Person> list = new ArrayList<Person>();
list.add(p1);
System.out.println("---------");
list.add(p2);
System.out.println("---------");
list.add(p3);
System.out.println("List size=" + list.size());
System.out.println("----分割线-----");
Set<Person> set = new HashSet<Person>();
set.add(p1);
System.out.println("---------");
set.add(p2);
System.out.println("---------");
set.add(p3);
System.out.println("Set size="+set.size());
}
static class Person{
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
System.out.println("Call equals();name="+name);
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return name.equals(person.name);
}
@Override
public int hashCode() {
System.out.println("Call hashCode(),age="+age);
return age;
}
}
}

The execution results of the above code are as follows:


---------
---------
List size=3
----分割线-----
Call hashCode(),age=10
---------
Call hashCode(),age=10
Call equals();name=lxp
---------
Call hashCode(),age=20
Set size=2

From the results When elements are added to the List, no additional operations are performed and can be repeated. Before adding the Set, you need to execute the hashCode method. If the returned value already exists in the set, you must continue to execute the equals method. If the result returned by the equals method is also true, it proves that the element already exists and the new element will be overwritten. Old elements, if the returned hashCode values ​​are different, are directly added to the collection. Remember here, for elements in the collection, elements with different hashCode values ​​must not be equal, but unequal elements may have the same hashCode value.


The difference between HashSet and LinkedHashSet is that the latter can ensure that the order of elements inserted into the set is consistent with the order of output. The difference between TresSet is that it is sorted according to Comparator. By default, it is arranged in ascending order according to the natural order of characters.


 (4)Iterable: From this figure you can see that the Collection class inherits from Iterable. The function of this interface is to provide the function of element traversal, that is to say, all collection classes (except Map-related class) all provide the function of element traversal. Iterable contains the iterator of Iterator. Its source code is as follows. If you are familiar with the iterator pattern, it should be easy to understand.

public interface Iterator<E> {
boolean hasNext();
E next();
void remove();
}

2. Map:

Map类型的集合最大的优点在于其查找效率比较高,理想情况下可以实现O(1)的时间复杂度。Map中最常用的是HashMap,LinkedHashMap与HashMap的区别在于前者能够保证插入集合的元素顺序与输出顺序一致。这两者与TreeMap的区别在于TreeMap是根据键值进行排序的,当然其底层的实现也有本质的区别,如HashMap底层是一个哈希表,而TreeMap的底层数据结构是一棵树。我们现在看下TreeMap与LinkedHashMap的区别:

package com.paddx.test.collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
public class MapTest {
public static void main(String[] args) {
Map<String,String> treeMap = new TreeMap<String,String>();
Map<String,String> linkedMap = new LinkedHashMap<String, String>();
treeMap.put("b",null);
treeMap.put("c",null);
treeMap.put("a",null);
for (Iterator<String> iter = treeMap.keySet().iterator();iter.hasNext();){
System.out.println("TreeMap="+iter.next());
}
System.out.println("----------分割线---------");
linkedMap.put("b",null);
linkedMap.put("c",null);
linkedMap.put("a",null);
for (Iterator<String> iter = linkedMap.keySet().iterator();iter.hasNext();){
System.out.println("LinkedHashMap="+iter.next());
}
}
}

运行上述代码,执行结果如下:

TreeMap=a
TreeMap=b
TreeMap=c
----------分割线---------
LinkedHashMap=b
LinkedHashMap=c
LinkedHashMap=a

  从运行结果可以很明显的看出这TreeMap和LinkedHashMap的区别,前者是按字符串排序进行输出的,而后者是根据插入顺序进行输出的。细心的读者可以发现,HashMap与TreeMap的区别,与之前提到的HashSet与TreeSet的区别是一致的,在后续进行源码分析的时候,我们可以看到HashSet和TreeSet本质上分别是通过HashMap和TreeMap来实现的,所以它们的区别自然也是相同的。HashTable现在已经很少使用了,与HashMap的主要区别是HashTable是线程安全的,不过由于其效率比较低,所以通常使用HashMap,在多线程环境下,通常用CurrentHashMap来代替。

三、总结

  本文只是从整体上介绍了Java集合框架及其继承关系。除了上述类,集合还提供Collections和Arrays两个工具类,此外,集合中排序跟Comparable和Comparator紧密相关。

The above is the detailed content of What is a collection class in Java? Explanation of collection class structure with graphic examples. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn