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.
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
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=2From 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.
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!