目录
UML关系图:
注:这是老版,新版还添加了其他的类
UML:统一建模语言
想更好的了解UML可以去这个网址:
UML类图几种关系的总结http://www.uml.org.cn/oobject/201609062.asp
元素有序,且可重复
下标,foreach,迭代器
利用反射机制
@Test public void listKuo() throws Exception { List<Integer> list=new ArrayList<>(); for (int i = 0; i <= 100; i++) { list.add(i); System.out.println("i:"+i); System.out.println("len:"+getListEleSize(list)); } } private int getListEleSize(List obj) throws Exception{ Class<? extends List> clazz=obj.getClass(); java.lang.reflect.Field f=clazz.getDeclaredField("elementData"); f.setAccessible(true); Object[] object= (Object[])f.get(obj); return object.length; }
- 简单数据结构,超出容量自动扩容,动态数组
- 内部实现是基于基础的对象数组的
- 随机访问快(最快)
- 不适合随机增加或删除
- 线程不安全
- LinkedList提供额外的get,remove,insert方法在LinkedList的首部或尾部
- 线程不安全
- LinkedList可被用作堆栈(stack)【包括了push,pop方法】,队列(queue)或双向队列(deque)
- 以双向链表实现,链表无容量限制,允许元素为null,线程不安全
- 适合做随机的增加或删除
- 线程安全
- 并行性能慢,不建议使用
- 写时复制
- 线程安全
- 适合于读多,写少的场景
- 写时复制出一个新的数组,完成插入、修改或者移除操作后将新数组赋值给array
- 比Vector性能高
- 最终一致性
- 实现了List接口,使用方式与ArrayList类似
设置下面这个方法,更方便检查
项目右键找到
点击Add Library中的JUnit,然后点击下一步
出现以下界面选择JUnit4,再应用就可以了
用Debug As中的JUnit Test运行
如果正确那么那个长框中就为绿色,错误为红色(如下图)
数据准备:为方便演示,需要有紧挨在一起的两个或多个相同的元素
- private List<Integer> list;//成员变量
-
- //每次运行都会执行Before方法
- @Before
- public void setup() {
- list = new ArrayList<>();
- list.add(1);
- list.add(2);
- list.add(3);
- list.add(3);
- list.add(4);
- }
各种输出方法
- /**
- * 删除集合中所有为3的元素
- */
- @Test
- public void remove01() {
- for (int i = 0; i < list.size(); i++) {
- if (list.get(i) == 3)
- list.remove(i);// 错误,因为数组下标会发生改变(移位)
- }
- System.out.println(list);// [1, 2, 3, 4]
- }
-
- @Test
- public void remove02() {
- for (int i = 0; i < list.size(); i++) {
- if (list.get(i) == 3)
- list.remove(i--);// 正确,删除之后下标往上移了一位,所以又识别到了3
- }
- System.out.println(list);// [1, 2, 4]
- }
-
- @Test
- public void remove03() {
- for (int i = list.size() - 1; i >= 0; i--) {
- if (list.get(i) == 3) {
- list.remove(i);// 正确,这是从后往前进行检测
- }
- }
- System.out.println(list);// [1, 2, 4]
- }
-
- @Test
- public void remove04() {
- for (Integer i : list) {
- if (i == 3)
- list.remove(i);// 错误,维护的值不相等了
- }
- System.out.println(list);
- }
-
- @Test
- public void remove05() {
- // 迭代器
- Iterator<Integer> it = list.iterator();
- while (it.hasNext()) {
- if (it.next() == 3) {
- it.remove();// 正确
- }
- }
- System.out.println(list);
- }
-
- @Test
- public void remove06() {
- 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 remove07() {
- list.remove(2);//删除下标为2的数
- System.out.println(list);//[1, 2, 3, 4]
- }
无序,不重复
foreach,迭代器
初始容量16,负载因子0.75,扩容增量1倍
- 它存储唯一元素并允许空值(依据对象的hashcode来确定该元素是否存在)
- 由HashMap支持
- 不保持插入顺序
- 非线程安全
- 性能参数:初始容量,负载因子(默认值: 初始容量16,负载因子0.75 示例:new HashSet<>(20, 0.5f);)
示例
package com.pf.dao; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.junit.Before; import org.junit.Test; public class SetDemo { private List<Integer> list = new ArrayList<>(); private Set<Integer> set = new HashSet<>(); @Before public void setup() { list.add(1); list.add(1); list.add(2); list.add(2); list.add(3); list.add(4); list.add(5); set.add(1); set.add(1); set.add(2); set.add(4); set.add(5); set.add(3); } /** * 去重 */ @Test public void test01() { List<Integer> tmp = new ArrayList<>(new HashSet<Integer>(list)); System.out.println(tmp); } @Test public void test02() { for(Integer e:set) { System.out.println(e); } } public void test03() { Iterator<Integer> it = set.iterator(); while(it.hasNext()) { System.out.println(it.next()); } } }
- 是一个包含有序的且没有重复元素的集合
- 作用是提供有序的Set集合,自然排序或者根据提供的Comparator进行排序
- TreeSet是基于TreeMap实现的
java.lang.Comparable
java.util.Comparator
第一种:根据sid进行的升序(如果想降序的话,只需要改成o2.getSid()-o1.getSid())
- package com.pf.dao;
-
- public class Student {
-
- private Integer sid;
- private String sname;
- private int 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 int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + age;
- 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 != 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 Student() {
- super();
- // TODO Auto-generated constructor stub
- }
- public Student(Integer sid, String sname, int age) {
- super();
- this.sid = sid;
- this.sname = sname;
- this.age = age;
- }
-
-
-
- }
- private List<Integer> list = new ArrayList<>();
-
- private Set<Integer> set = new HashSet<>();
-
- @Before
- public void setup() {
- list.add(1);
- list.add(1);
- list.add(2);
- list.add(2);
- list.add(3);
- list.add(4);
- list.add(5);
-
- set.add(1);
- set.add(1);
- set.add(2);
- set.add(4);
- set.add(5);
- set.add(3);
- }
-
- @Test
- public void test04() {
- TreeSet<Student> stu = new TreeSet<>(new Comparator<Student>() {
- @Override
- public int compare(Student o1, Student o2) {//排序
- return o1.getSid()-o2.getSid();
- }
- });
-
-
- stu.add(new Student(1,"zs", 18));
- stu.add(new Student(1,"zs", 18));
- stu.add(new Student(2,"ls", 19));
- stu.add(new Student(4,"lihao", 10));
- stu.add(new Student(7,"lihao", 18));
- stu.add(new Student(5,"zengfanyan", 20));
- stu.add(new Student(3,"we", 30));
-
- //删除
- //stu.remove(new Student(4, "lihao", 10));
-
- for(Student s: stu) {
- System.out.println(s);
- }
- }
效果图:
第二种:
在实体类(student)中继承一个接口
public class Student implements Comparable<Student>{
然后实现一个方法
- @Override
- public int compareTo(Student o) {
- return this.getSid() - o.getSid();
- }
最后再测试类中把排序删掉
- @Test
- public void test04() {
- TreeSet<Student> stu = new TreeSet<>();
-
-
- stu.add(new Student(1,"zs", 18));
- stu.add(new Student(1,"zs", 18));
- stu.add(new Student(2,"ls", 19));
- stu.add(new Student(4,"lihao", 10));
- stu.add(new Student(7,"lihao", 18));
- stu.add(new Student(5,"zengfanyan", 20));
- stu.add(new Student(3,"we", 30));
-
- //删除
- //stu.remove(new Student(4, "lihao", 10));
-
- for(Student s: stu) {
- System.out.println(s);
- }
- }
无序,键值对,键不能重复,值可以重复,键重复则覆盖,没有继承Collection接口
初始容量16,负载因子0.75,扩容增量1倍
先获取所有键的Set集合,再遍历(通过键获取值)
取出保存所有Entry的Set,再遍历此Set即可
- package com.pf.dao;
-
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.Map;
- import java.util.Map.Entry;
-
- import org.junit.Before;
- import org.junit.Test;
-
- public class MapDemo {
-
- private Map<String, Object> map=new HashMap<String, Object>();
-
- @Before
- public void setup() {
- map.put("1", "zhuzhu");
- map.put("1", "aa");
- map.put("2", "she");
- map.put("3", "he");
-
- //如果键值对没有就添加进去
- map.putIfAbsent("1", "zzz");
- }
-
- @Test
- public void test01() {
- Iterator<String> it = map.keySet().iterator();//通过获取键的集合来获取迭代器
- while(it.hasNext()) {
- String key=it.next();
- System.out.println(map.get(key));
- }
- }
-
- @Test
- public void test02() {
- Iterator<Entry<String, Object>> it = map.entrySet().iterator();
- //比上面的方法略微快一点点,如果对所有的map集合一次遍历完成之后都要去处理的话,就用这种更好
- while(it.hasNext()) {
- Entry<String, Object> e = it.next();
- System.out.println("key = " + e.getKey()+"value = "+e.getValue());
- }
- }
-
- }
- 线程不安全,最常用,速度快
- 内部采用数组来存放数据
基本原理:
put执行过程
Table数组中的的Node
1》链表结构示意图
2》红黑树结构示意图
红黑树是什么?红黑树特点有哪些?-奇Q工具网对于红黑树你了解多少呢?很多刚刚接触java的人都不知道红黑树是什么,那么下面就一起来看一下红黑树的概念以及它的特点吧!一、什么是红黑树?红黑树,是一种自平衡二叉查找树,是在计算机科学当中,所用到的一种数据结构,最典型的用途就是实现关联数组。红黑树是一种特化的AVL树,也就是平衡二叉树,都是在进行插入和删除操作的的时候,通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。红黑树是复杂的,可是,它的最坏情况运行时间也是非常良好的,并且在实践中是高效的。红黑树可以在O(log n)时间内做查找https://qqe2.com/java/post/1321.html 可以在下面网站中测试(可以在这个网站学习数据类型)Data Structure Visualization http://www.rmboot.com/注:流程图中绿色标出的部分为JDK8新增的处理逻辑,目的是在Table[i]中的Node节点数量大于8时,通过红黑树提升查找速度。
线程安全,不太常用
@Test public void test03() { Map<Integer, Object> table = new Hashtable<Integer, Object>(); table.put(1, "zfm"); table.put(2, "zfm2"); table.put(3, "zfm3"); table.put(4, "zfm4"); Iterator<Integer> it = table.keySet().iterator(); while(it.hasNext()) { int key=it.next(); System.out.println(table.get(key)); } }
线程安全,比HashTable性能高(一桶一锁,加强比较并替换操作)
@Test public void test04() { Map<Integer, Object> cmap = new ConcurrentHashMap<Integer, Object>(); cmap.put(1, "zfm"); cmap.put(2, "zfm2"); cmap.put(3, "zfm3"); cmap.put(4, "zfm4"); Iterator<Integer> it = cmap.keySet().iterator(); while(it.hasNext()) { int key=it.next(); System.out.println(cmap.get(key)); } }
- key值按一定的顺序排序
- 添加或获取元素时性能较HashMap慢(因为需求维护内部的红黑树,用于保证key值的顺序)
这是降序排列
@Test public void test05() { TreeMap<Integer, Object> treeMap = new TreeMap<Integer, Object>(new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return o2 - o1; } }); treeMap.put(1, "zs1"); treeMap.put(3, "zs3"); treeMap.put(2, "zs2"); treeMap.put(4, "zs4"); Iterator<Integer> it = treeMap.keySet().iterator(); while(it.hasNext()) { int key = it.next(); System.out.println(treeMap.get(key)); } }注:如果在new的时候不记得了可以按住Ctrl键再将鼠标移到TreeMap上点击就可以跳转源代码进行查看了
- 继承HashMap
- LinkedHashMap是有序的,且默认为插入顺序(当我们希望有顺序地去存储key-value时,就需要使用LinkedHashMap了)
@Test public void test06() { Map<String, String> linkedHashMap = new LinkedHashMap<>(); linkedHashMap.put("name1", "josan1"); linkedHashMap.put("name2", "josan2"); linkedHashMap.put("name3", "josan3"); 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); } }
工具类