Table of contents
Collection class diagram
In UML class diagrams, there are several common relationships:
Generalization : It is an inheritance relationship that represents general and special relationships, specifying how subclasses specialize all characteristic behaviors of parent classes. For example: Tiger is a kind of animal, that is, the characteristics of tigers also have the commonalities of animals
Implementation : The relationship between a class and an interface , representing the implementation of all features and behaviors of the interface.
Association: It is an owned relationship that enables one class to know the properties and methods of another class. Associations are divided into two-way and one-way. For example, a teacher and a student are two-way related, a teacher has multiple students, and a student may have multiple teachers. However, the relationship between students and a course is a one-way association. A student may take multiple courses. The course is an abstract thing and he does not own students.
Aggregation : The relationship between the whole and the parts, and the parts can exist independently of the whole . For example: a car and a tire are a whole-part relationship, and the tire can still exist when it leaves the car
Combination : It is the relationship between the whole and the part. Without a company, there is no department . The composition relationship is a kind of association relationship, which is stronger than the aggregation relationship . It requires the object representing the whole in the ordinary aggregation relationship to be responsible for the life cycle of the object representing the part.
Dependency : It is a relationship of use , that is, the implementation of one class requires the assistance of another class, so try not to use two-way interdependence.
Strong and weak order of relationships: generalization = realization > composition > aggregation > association > dependency
List collection
List collection features: elements are ordered and repeatable
Traversal methods: subscript, foreach, iterator
List collection implementation methods: ArrayList, LinkedList, Vector, CopyOnWriteArrayList
Using junit test , the code is simpler
Basic traversal loop method
@Test
public void listAdd() {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(3);
list.add(5);
list.add(4);
System.out.println(list);
}
private List<Integer> list = new ArrayList<>();
@Before
public void setup() {
list.add(1);
list.add(3);
list.add(5);
list.add(4);
}
// 第一种遍历方法
@Test
public void list1() {
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
//第二种遍历方法
@Test
public void list2() {
for (Integer integer : list) {
System.out.println(integer);
}
}
//迭代器
@Test
public void list3() {
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
ArrayList is the most commonly used collection
Features: 1. Simple data structure, automatic expansion beyond capacity, dynamic array
2, the internal implementation is based on the underlying object array
3. Fast random access
Disadvantages: 1. Not suitable for random addition or deletion
2, thread unsafe
ListedList
Features: 1. LinkedList provides additional get, remove, and insert methods at the head or tail
of LinkedList 2. LinkedList can be used as a stack (including push, pop methods), queue (queue) or two-way queue (deque)
3. Implemented with a doubly linked list, the linked list has no capacity limit, allows elements to be null, and is thread unsafe
4. Suitable for random addition or deletionVector
The internal implementation of Vector is similar to ArrayList. It supports thread synchronization, and only one thread can write to Vector at a time. But the cost is high, so accessing Vector is slower than accessing ArrayList. (thread safe, slow parallel performance)
CopyOnWriteArrayList
Features: 1. Copy-on-write
2. Thread safety
3. Suitable for scenarios with more reads and less
writes 4. Copy a new array when writing, and assign the new array to array after inserting, modifying or removing operations
5. Higher performance than Vector
6, eventual consistency
7, implements the List interface, and is used in a similar way to ArrayList
ArrayList delete method
package com.zking.list;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
public class ListDamo2 {
private List<Integer> list;
@Before
public void setup() {
list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(3);
list.add(4);
}
// 下标循环删除方式1
@Test
public void remove1() {
for (int i = 0; i < list.size(); i++) {
if (list.get(i) == 3)
list.remove(i);
}
System.out.println(list);
}
// 下标循环删除方式2
@Test
public void remove2() {
for (int i = 0; i < list.size(); i++) {
if (list.get(i) == 3)
list.remove(i--);
}
System.out.println(list);
}
// 下标循环倒序删除
@Test
public void remove3() {
for (int i = list.size() - 1; i >= 0; i--) {
if (list.get(i) == 3)
list.remove(i);
}
System.out.println(list);
}
// foreach循环删除
@Test
public void remove4() {
for (Integer integer : list) {
if (integer == 3)
list.remove(integer);
}
System.out.println(list);
}
// 第五种删除方法
@Test
public void remove5() {
Iterator<Integer> it = list.iterator();
while (it.hasNext()) {
if (it.next() == 3) {
it.remove();
}
}
System.out.println(list);
}
// 第六种删除方法
@Test
public void remove6() {
Iterator<Integer> it = list.iterator();
while (it.hasNext()) {
Integer value = it.next();
if (value == 3) {
list.remove(value);
}
}
System.out.println(list);
}
// 删除的参数是基本型的函数
@Test
public void remove7() {
list.remove(2);
System.out.println(list);
}
}
Set collection
Set collection features: elements are unordered and not repeated
Traversal methods: foreach, iterator
Set collection implementation method: Hashset, TreeSet
It stores unique elements and allows null values (determines whether the element exists
according to the hashcode of the object) Determines whether the element exists according to the hashcode of the object
Backed by HashMap
Does not maintain insertion order
Not thread safe
Thinking about a problem?
1. How to deduplicate the elements in the list container?
2. How to deduplicate the ArrayList collection
First throw the duplicate list into HashSet, use HashSet to remove the duplicate data, and then find a new ArrayList through HashSet.
public class SetDamo { private List<Integer> list = new ArrayList<>(); @Before public void setup() { list.add(1); list.add(1); list.add(2); list.add(2); list.add(3); list.add(3); } @Test public void set1() { List<Integer> list2 = new ArrayList<>(new HashSet<Integer>(list)); System.out.println(list2); }
The results are as follows:
3. Does set have the problem of deleting by subscript in ArrayList, or deleting by foreach loop? why
set is an unordered collection, without subscripts, there is no way to obtain by subscripts, only through foreach loop or iterator
4. Does the set have List deletion? The incoming integer needs to be distinguished from the basic type or the object type. Why?Example: list.remove(Integer.valueof(2)); is an object type,
list.remove(2); is the basic type
Both results are different
However, the set collection has no subscript and is deleted directly through the object
5. How is HashSet implemented?Implemented by map Because map is a key-value pair, the key cannot be repeated, the value can be repeated, and the value is stored in the key. Only the key is used and no value is used at runtime
Write the student class
package com.zking.set; public class Student { private Integer sid; private String sname; private Integer age; public Student(Integer sid, String sname, Integer age) { super(); this.sid = sid; this.sname = sname; this.age = age; } public Integer getSid() { return sid; } public void setSid(Integer sid) { this.sid = sid; } public String getSname() { return sname; } public void setSname(String sname) { this.sname = sname; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((age == null) ? 0 : age.hashCode()); result = prime * result + ((sid == null) ? 0 : sid.hashCode()); result = prime * result + ((sname == null) ? 0 : sname.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Student other = (Student) obj; if (age == null) { if (other.age != null) return false; } else if (!age.equals(other.age)) return false; if (sid == null) { if (other.sid != null) return false; } else if (!sid.equals(other.sid)) return false; if (sname == null) { if (other.sname != null) return false; } else if (!sname.equals(other.sname)) return false; return true; } @Override public String toString() { return "Student [sid=" + sid + ", sname=" + sname + ", age=" + age + "]"; } }
public class SetDamo { @Test public void set2() { Set<Student> stu = new HashSet<>(); stu.add(new Student(1, "hh", 18)); stu.add(new Student(1, "hh", 18)); stu.add(new Student(2, "aa", 19)); stu.add(new Student(2, "aa", 19)); for (Student student : stu) { System.out.println(student); } } }
The results are as follows:
TreeSet collection features: elements are ordered, and there is no repetition
Function: Provide an ordered Set collection, natural sorting or sorting according to the provided Comparator
TreeSet is implemented based on TreeMap
- The HashSet collection is unordered, and sometimes an ordered collection is required, in which case TreeSet can be used.
- When using TreeSet to store objects, the add() method will automatically call the compareTo() method for comparison.
- Use the binary tree form to store according to the comparison result. (TreeSet is implemented directly using TreeMap)
Natural sorting:
//如果保存的是数值型,则按数值排序 @Test public void set4() { TreeSet<Integer> set=new TreeSet<>(); set.add(4); set.add(2); set.add(3); set.add(1); System.out.println(set); } //如果保存的是字符,则按字符对应的ASCII进行排序 @Test public void demo2() { TreeSet<String> ts = new TreeSet<>(); ts.add("a"); ts.add("d"); ts.add("b"); ts.add("c"); System.out.println(ts); }
Comparator sorting _
TreeSet passes in the comparator through the constructor
@Test public void set4() { TreeSet<Integer> set = new TreeSet<>(new Comparator<Integer>() { // 比较方法 @Override public int compare(Integer o1, Integer o2) { return o2 - o1; } }); set.add(4); set.add(2); set.add(3); set.add(1); System.out.println(set); }
operation result:
Implement the sorting interface
@Test public void set6() { TreeSet<Student> set = new TreeSet<>(new Comparator<Student>() { // 比较方法 @Override public int compare(Student o1, Student o2) { return o2.getAge() - o1.getAge(); } }); set.add(new Student(1, "aa", 18)); set.add(new Student(2, "bb", 19)); set.add(new Student(3, "cc", 20)); set.add(new Student(4, "dd", 21)); for (Student student : set) { System.out.println(student); } }
Write the Student class to implement the interface
package com.zking.set; public class Student implements Comparable<Student>{ private Integer sid; private String sname; private Integer age; public Student(Integer sid, String sname, Integer age) { super(); this.sid = sid; this.sname = sname; this.age = age; } public Integer getSid() { return sid; } public void setSid(Integer sid) { this.sid = sid; } public String getSname() { return sname; } public void setSname(String sname) { this.sname = sname; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((age == null) ? 0 : age.hashCode()); result = prime * result + ((sid == null) ? 0 : sid.hashCode()); result = prime * result + ((sname == null) ? 0 : sname.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Student other = (Student) obj; if (age == null) { if (other.age != null) return false; } else if (!age.equals(other.age)) return false; if (sid == null) { if (other.sid != null) return false; } else if (!sid.equals(other.sid)) return false; if (sname == null) { if (other.sname != null) return false; } else if (!sname.equals(other.sname)) return false; return true; } @Override public String toString() { return "Student [sid=" + sid + ", sname=" + sname + ", age=" + age + "]"; } @Override public int compareTo(Student o) { if (this.getAge()==o.getAge()) { return o.getSid()-this.getSid(); } return o.getAge()-this.getAge(); } }
@Test public void set6() { TreeSet<Student> set = new TreeSet<>(); set.add(new Student(1, "aa", 18)); set.add(new Student(5, "ee", 18)); set.add(new Student(2, "bb", 19)); set.add(new Student(3, "cc", 20)); set.add(new Student(4, "dd", 21)); for (Student student : set) { System.out.println(student); } }
operation result:
Map collection
Map collection features: unordered, it is a key-value pair, the key cannot be repeated, and the value can be repeated; if the key is repeated, it is overwritten, and the Collection interface is not inherited
Traversal method: first get the Set collection of all keys, then traverse (get the value through the key); take out the Set that holds all the Entry, and then traverse the Set
Map collection implementation methods: HashMap, HashTable, ConcurrentHashMap, TreeMap, LinkedHashMap
HashMap collection features: thread-unsafe, most commonly used, fast; internal use of arrays to store data
Basic principle: put execution process
Node in Table array
Schematic diagram of linked list structure
Schematic diagram of red-black tree structure
The part marked in green in the flowchart is the new processing logic of JDK8. The purpose is to improve the search speed through the red-black tree when the number of Node nodes in Table[i] is greater than 8.
public class MapDamo { private Map<String, Object> map = new HashMap<>(); @Before public void setup() { map.put("1", "aa"); map.put("1", "aa"); map.put("2", "bb"); map.put("3", "cc"); map.put("4", "dd"); } @Test public void map1() { Iterator<String> it = map.keySet().iterator(); while (it.hasNext()) { String key = it.next();// 获取键 String object = (String) map.get(key);// 获取值 System.out.println(object); } } @Test public void map2() { Iterator<Entry<String, Object>> it = map.entrySet().iterator(); // 遍历所有集合 while (it.hasNext()) { Entry<String, Object> entry = it.next(); System.out.println("key=" + entry.getKey() + " value=" + entry.getValue()); } }
- When map1 loops, the key value is the same, and the back covers the front
- map2 entry can be understood as an entity, including two values (key, value) in the entity object
HashTable: thread safe, less commonly used
@Test public void map3() { Map<String, Object> table = new HashMap<>(); table.put("1", "aa"); table.put("1", "bb"); table.put("2", "cc"); table.put("3", "dd"); Iterator<String> it = table.keySet().iterator(); while (it.hasNext()) { String key = it.next(); System.out.println(table.get(key)); } System.out.println("------------"); Iterator<Entry<String, Object>> it1 = table.entrySet().iterator(); while (it1.hasNext()) { Entry<String, Object> entry = it1.next(); System.out.println("key=" + entry.getKey() + " value=" + entry.getValue()); } }
operation result:
ConcurrentHashMap: thread-safe, higher performance than HashTable
@Test public void map4() { Map<String, Object> map = new ConcurrentHashMap<>(); map.put("1", "aa"); map.put("1", "bb"); map.put("2", "cc"); map.put("3", "dd"); map.put("4", "ee"); Iterator<String> it = map.keySet().iterator(); while (it.hasNext()) { String key = it.next();// 获取键 String object = (String) map.get(key);// 获取值 System.out.println(object); } }
operation result:
TreeMap: The key values are sorted in a certain order; the performance is slower than that of HashMap when adding or obtaining elements; because the internal red-black tree needs to be maintained to ensure the order of key values@Test public void map5() { TreeMap<Integer, String> treeMap = new TreeMap<>(new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return o1-o2; } }); treeMap.put(1, "zs"); treeMap.put(2, "ls"); treeMap.put(3, "ww"); Iterator<Integer> it = treeMap.keySet().iterator(); while (it.hasNext()) { Integer key = it.next();// 获取键 String object = (String) treeMap.get(key);// 获取值 System.out.println(object); } }
operation result:
LinkedHashMap features: inherits the HasMap collection; ordered and defaults to the insertion order; when we want to store key-values in order, we need to use LinkedHashMap
@Test public void map6() { Map<String, String> linkedHashMap = new LinkedHashMap<>(); linkedHashMap.put("1", "张三"); linkedHashMap.put("2", "李四"); linkedHashMap.put("3", "王五"); Set<Entry<String, String>> set = linkedHashMap.entrySet(); Iterator<Entry<String, String>> iterator = set.iterator(); while (iterator.hasNext()) { Entry entry = iterator.next(); String key = (String) entry.getKey(); String value = (String) entry.getValue(); System.out.println("key:" + key + ",value:" + value); } }
operation result: