集合类图,如下所示
list集合
遍历方式:下标,forEach,迭代器(小编推荐使用)
初始化
List<Integer> list = new ArrayList<>(); //初始化 @Before public void setup() { list.add(1); list.add(3); list.add(3); list.add(4); list.add(2); }
结果:[1,3,3,4,2]
@Test //迭代器遍历 public void test03() { Iterator<Integer> iterator = list.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } }
list集合怎么删除元素??
@Test //最好用迭代器删除,不易出错 public void test04() { Iterator<Integer> iterator = list.iterator(); while (iterator.hasNext()) { if(iterator.next()==3) { iterator.remove(); } } System.out.println(list); }
注意事项:
结果:[1,3, 2]
@Test public void test05() { list.remove(3); list.remove(Integer.valueOf(3)); System.out.println(list); }
list.remove(3);删除的是指定下标;
list.remove(Integer.valueOf(3));删除的一个指定的对象;
实现目标:[1,4,2]
结果:[1,3,4,2]
@Test public void test01() { for (int i = 0; i < list.size(); i++) { if(list.get(i)==3) { list.remove(i); } } System.out.println(list); }
解决方案
@Test public void test01() { for (int i = 0; i < list.size(); i++) { if(list.get(i)==3) { list.remove(i--); } } System.out.println(list); }
小编经验:当找到为第一个3(下标1)的下标时,删除之后,第一个3就为空了;第二个3(下标2)往前挤了一个下标,变成了(下标1)
Arraylist的一些特性:
简单数据结构,超出容量自动扩容,动态数组
内部实现是基于基础的对象数组的
随机访问快
不适合随机增加或删除
线程不安全
LinkedList的一些特性:
LinkedList可被用作堆栈(stack)【包括了push,pop方法】,队列(queue)或双向队(deque)
Vector:线程安全(单独使用线程,等它使用完别人才能使用),性能慢。
CopyOnWriteArrayList的一些特性:
写的时候复制,完成所有操作后,将已经操作完成的数据直接给array,保持了最终一致性。
Set集合
遍历方式:forEach,迭代器
特点:无序,不重复
HashSet集合
它存储唯一元素并允许空值,不保持插入顺序
下面是去重例子
结果:[1,2,3]
初始化
private List<Integer> list = new ArrayList<>(); private Set<Integer> set=new HashSet<Integer>(); @Before public void satrt() { list.add(1); list.add(2); list.add(1); list.add(2); list.add(3); list.add(3); set.add(1); set.add(1); set.add(2); set.add(3); set.add(3); set.add(2); }
@Test public void test01() { List<Integer> sa=new ArrayList<>(new HashSet<Integer>(list)); System.out.println(sa);//给list去重 } @Test public void test02() { for(Integer e: set) { System.out.println(e); } }
TreeSet集合
是一个包含有序的且没有重复元素的集合,作用是提供有序的Set集合
自然排序或者根据提供的Comparator进行排序
TreeSet集合与HashSet的区别,插入结果是否进行排序。
error错误类型转换异常:
ClassCastExcption类转换异常,stu.add(new Student(1, "zs", 12))添加不进去。
解决方法:实现Comparable(比较器),然后重写比较器的方法即可。
按年龄排序结果如下
Student [sid=7, sname=lihao, age=1] Student [sid=4, sname=lihao, age=10] Student [sid=1, sname=zs, age=12] Student [sid=2, sname=ls, age=19] Student [sid=5, sname=zengfanyan, age=20] Student [sid=3, sname=we, age=30]
Test
@Test public void test04() { Set<Student> stu = new TreeSet<Student>(); stu.add(new Student(1, "zs", 12)); stu.add(new Student(2,"ls", 19)); stu.add(new Student(4,"lihao", 10)); stu.add(new Student(7,"lihao", 1)); stu.add(new Student(5,"zengfanyan", 20)); stu.add(new Student(3,"we", 30)); for(Student s: stu) { System.out.println(s); } }
Student实体必须实现Comparable(比较器)
比较者大于被比较者 返回1
比较者等于被比较者 返回0
比较者小于被比较者 返回-1
写法一public class Student implements Comparable<Student>{ @Override public int compareTo(Student o) { if(this.getAge()-o.getAge()==0) { return this.getSid()-o.getSid(); } return this.getAge()-o.getAge(); }
写法二public class Student implements Comparable<Student>{ @Override public int compareTo(Student o) { if(this.getSid()>o.getSid()) { return 1; }else{ if(this.getSid()==o.getSid()) { return 0; }else{ if(this.getSid()<o.getSid()){ return -1; } } }
上面代码与这个代码一样的
写法三return this.getAge()-o.getAge();
Map集合
特点:无序,键值对现实存在,键不能重复,值可以重复
如果键重复则覆盖,没有继承Collection接口
遍历方式
初始化
Map<String, String> map=new TreeMap<>(); @Before public void satrtUp() { map.put("1", "lkf"); map.put("2", "zs"); map.put("3", "ls"); map.put("4", "wu"); map.put("5", "ll"); }
通过keySet遍历
先获取所有键的Set集合,再遍历(通过键获取值)
结果:[lkf,zs,ls,wu,ll]
/** * 获取HashMap集合上的键的集合,保存ketSet集合里,然后使用ketSet集合自己的迭代器遍历 */ @Test public void test01() { Iterator<String> iterator = map.keySet().iterator(); while (iterator.hasNext()) { String Key = iterator.next(); System.out.println(map.get(Key)); } }
通过entrySet遍历
取出保存所有Entry的Set,再遍历此Set即可
结果:[1:kk,2:yy,3:zz]
@Test public void test02() { Map<String, String> maps=new HashMap<>(); maps.put("1", "kk"); maps.put("2", "yy"); maps.put("3", "zz"); Iterator<Entry<String, String>> iterator = maps.entrySet().iterator();//通过enrty获取自身的迭代器 while (iterator.hasNext()) {//hasNext()判断该迭代器有无元素 Entry<String, String> next = iterator.next();//entrySet()可获取键和值,属于一个集合 System.out.println(next.getKey()+":"+next.getValue()); } }
如何对已存在的key为1的记录进行了覆盖???
原结果:[1:lkf,2:zs,3:ls,4:wu,5:ll]
现结果:[1:yyy,2:zs,3:ls,4:wu,5:ll]
@Test public void test06() { //对已存在的key为1的记录进行了覆盖 map.put("1", "yyy"); Iterator<Entry<String, String>> iterator = map.entrySet().iterator(); while (iterator.hasNext()) {//hasNext()判断该迭代器有无元素 Entry<String, String> next = iterator.next();//entrySet()可获取键和值,一个集合 System.out.println(next.getKey()+":"+next.getValue()); } }
HashMap集合
特点:线程不安全,最常用,速度快
基本原理:内部采用数组来存放数据
红黑树结果示图
红黑树怎么查找数据的?
通过数组下标,先找到指定下标的元素比较大小;如果比上一个元素下标大,就继续往下找,该链条上下一个元素下标;直到找到比该元素小的下标为止。
链条查找元素一般的找靠right(右边)的元素
TreeMap集合
key值按一定的顺序排序,但是比HashMap慢;因为需求维护内部的红黑树,用于保证key值的顺序
Map<String, Student> tree=new TreeMap<String, Student>(); @Before public void satrtUp() { tree.put("1", new Student(1, "zs",11)); tree.put("2", new Student(2,"sb",12)); tree.put("3", new Student(3,"ljj",13)); tree.put("4", new Student(4,"zyz",14)); tree.put("5", new Student(5,"yyxq",15)); }
结果如下:
1:Student [sid=1, sname=zs, age=11] 2:Student [sid=2, sname=sb, age=12] 3:Student [sid=3, sname=ljj, age=13] 4:Student [sid=4, sname=zyz, age=14] 5:Student [sid=5, sname=yyxq, age=15]
@Test public void demo01() { tree.forEach((key, val) -> System.out.println(key + ":" + val)); }
linkedHashMap集合
LinkedHashMap是有序的,且默认为插入顺序;
使用环境:当我们希望有顺序地去存储key-value时,就需要使用LinkedHashMap了
结果如下
1:Student [sid=1, sname=zs, age=11] 2:Student [sid=2, sname=sb, age=12] 3:Student [sid=3, sname=ljj, age=13] 4:Student [sid=4, sname=zyz, age=14] 5:Student [sid=5, sname=yyxq, age=15]
/** * linkedHashMap遍历 */ @Test public void demo02() { Map<String, String> link=new LinkedHashMap<>(); Set<Entry<String,String>> entrySet = link.entrySet();//获取entrySet集合 Iterator<Entry<String, String>> iterator = entrySet.iterator();//通过enrty获取自身的迭代器 while (iterator.hasNext()) { Entry<String, String> next = iterator.next();//entrySet()可获取键和值,属于一个集合 System.out.println(next.getKey()+":"+next.getValue()); } }