Several collection classes commonly used in java and their implementation methods

Table of contents

Collection class diagram

List collection

Set collection

Map collection


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 deletion

Vector

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:

Guess you like

Origin blog.csdn.net/qq_64001795/article/details/125576319