对应结构图讲解各个接口与实现类之间的关系:
Collection
├ List (有序集合,允许相同元素和null)
│ ├LinkedList (非同步,允许相同元素和null,遍历效率低插入和删除效率高)
│ ├ArrayList (非同步,允许相同元素和null,实现了动态大小的数组,遍历效率高,用的多)
│ └Vector(同步,允许相同元素和null,效率低)
│ ├ Set (无序集合,不允许相同元素,最多有一个null元素)
| └HashSet(无序集合,不允许相同元素,最多有一个null元素)
Collection顶级接口
Collection是最基本的集合接口(也可以称为顶级接口)
在Collection的实例中,有些实例允许相同的元素,有些则不允许,还有一些能内置实现排序功能,所以 根据存储数据的方式(数据结构)各有不同,所以存储的容器也就有多种,从而形成了集合框架这一体 系
同时,在Java中不提供直接继承自Collection的类,Java所提供的类都是继承自Collection的“子接口”: List和Set
常用的方法
boolean add(Object o) 添加对象到集合
boolean remove(Object o) 删除指定的对象
int size() 返回当前集合中元素的数量
boolean contains(Object o) 查找集合中是否有指定的对象
boolean isEmpty() 判断集合是否为空
Iterator iterator() 返回一个迭代器
boolean containsAll(Collection c) 查找集合中是否有集合c中的元素
boolean addAll(Collection c) 将集合c中所有的元素添加给该集合
void clear() 删除集合中所有元素
void removeAll(Collection c) 从集合中删除c集合中也有的元素
void retainAll(Collection c) 从集合中删除集合c中不包含的元素
关于Collection的遍历操作:Iterable接口与Iterator接口
查看Collection的源代码
得出结论:
Collection下的集合都间接继承了Iterable
观看Iterable接口源码
因为Collection继承了Iterable,所以它以下的实现类也都会具备 iterator() 这个方法
我们可以通过这个方法来获得一个 Iterator ,也就是一个迭代器
关于迭代器中的方法,我们可以通过查看 Iterator 的源码
方法的作用:
hasNext: 判断是否存在下一个元素(遍历完成没有)
next:让遍历的位置下移,同时获得下移后集合中对应的元素
remove:删除当前的元素
通过画图法来让学生理解迭代器的运行原理
当Iterator对象创建完成时,这时的指针其实指向的是第一个元素的上方,即指向一个空
调用hasNext方法时,判断当前箭头的下一个是否存在(集合是否到了末尾,然后返回boolean类 型)
调用next方法时,箭头向下移动一位,并且返回箭头所在的元素
调用remove方法时,移除当前箭头所在的元素
使用ArrayList来演示迭代器的使用
ArrayList<Object> cs=new ArrayList<Object>();//里氏替换原则 //向集合中添加数据 cs.add("1"); cs.add("2"); cs.add("3"); cs.add("4"); cs.add("5"); cs.add("6"); System.out.println("集合的原有长度:"+cs.size()); Iterator<Object> i = cs.iterator();//获得该集合的迭代器 while(i.hasNext()) {//判断迭代器中是否存在下一个元素 System.out.println(i.next());//指针向下移动一位,并取出对应元素(对应上图讲解) i.remove();//移除指针对应的元素 } System.out.println("集合的长度:"+cs.size());
结果
List集合与其实现类
Collection的子接口,这个接口所具备的特征: 可重复 , 有序
可重复:在集合内部,一个元素可以出现多次,也就是在集合中可以占有多个位置 Person p=new Person(); List<Person> ls=new ArrayList<Person>(); ls.add(p); ls.add(p); ls.add(p); 观察这个代码,说出集合的长度 size=3 得出结论: p这个元素在集合中重复了三次,占了三个位置,这就是可重复
有序理解
List中的有序指的不是内部的元素会以某种格式排序,而是指其中的每个元素在进入集合时都是有添加顺序的 先添加的在前面,后添加的在后面,这些位置是有序的 也就是 0,1,2,3,4.... (我们称之为下标) List<String> ls=new ArrayList<String>(); ls.add("jack"); ls.add("mary"); ls.add("eason"); jack的下标是1 mary的下标是2 eason的下标是3 add这个方法是在集合的最后一位添加元素,下标也就会随着变大 在add的时候还可以指定当前添加的元素的位置 -> ls.add(2,"asong"); 将 asong 放入集合的第2位 未添加 asong 时: [jack, mary, eason] 添加了 asong 后: [jack, mary, asong, eason] 需要注意的是,指定的位置必须小于当前集合的最大下标 同时,因为List是有序的,我们除了可以按照顺序(下标)插入之外,也可以按照顺序(下标)来读取与删除 读取: ls.get(0),根据下标来读取的方式我们一般称为随机读取 删除: ls.remove(0) 根据下标移除第0位 ls.remove("jack") 移除集合中的 jack ,集合中是使用equals来判断的
在添加元素的时候,集合的长度是随着元素的增多而随之增多的,但是不会每次都+1,而是有着自己的 扩容机制
以ArrayList而言:
List<String> ls=new ArrayList<String>(15);
因为无参实例集合的初始长度为10,当我们添加的元素超过10位的时候,集合的大小就不够了,需要扩 容
每次添加的时候,都调用grow方法判断是否需要扩容
ArrayList的扩容因子是1.5 : 原容量的0.5倍
ArrayList的容量为10,一次扩容后是容量为15
List实现类的不同特征
根据数据结构的不同,List底下的实现类可以分为两种: 对象数组结构 , 联表结构
对象数组结构
特点:基于对象数组,拥有下标,每次扩容的时候其实都是新建了一个更大的数组,然后将原有内容复 制过去
ArrayList 增删慢,查询快,有连续下标,线程不同步(不安全),扩容因子为1.5
Vector 增删改查都慢,有连续下标,线程同步(安全),扩容因子为2
查看两个类中,相同方法的区别(突出线程的同步)
基于对象数组的集合最大的好处就是读取非常快,因为是随机读取,但是修改的速度比较慢,如果在项 目中遇到了需要非常频繁的对集合中的元素进行修改的操作,可以使用链表结构的集合
链表结构
Linkedlist 链表结构,增删快,查询慢,没有连续下标
使用画图法演示如链表结构中如何中新增元素,同时对比对象数组的新增,凸显链表的速度体现
链表中修改只需要一次
同理,图演法演示链表的读取与对象数组的读取
随机读取只要一次,链表需要从头读到尾
展示链表的类型:
LinkList的使用
LinkedList<String> ls=new LinkedList<String>(); ls.add("jack"); ls.add("jack1"); ls.add("jack2"); ls.add("jack3"); System.out.println(ls.get(1));//jack1 虽然我们是通过下标来取值,但是在内部,还是得从链表开头一直查,查询到链表的对应位置
LinkList特有方法
addFirst(); 添加在第一个 addLast(); 添加在最后一个 getFirst(); 得到第一个 getLast(); 得到最后一个 removeFirst(); 移除第一个 removeLast(); 移除最后一个
标签:J2EE,下标,元素,list,Collection,add,ls,集合 From: https://www.cnblogs.com/wujingyu123/p/17004184.html