🥳🥳Welcome Huihui's Code World ! !🥳🥳
接下来看看由辉辉所写的关于单列集合的相关操作吧
目录
🥳🥳Welcome Huihui's Code World ! !🥳🥳
💡辉辉小贴士:由于List集合中的数据是不唯一,代表可以重复,那么怎么让它里面的元素不重复呢?
💡辉辉小贴士linked:怎么用LinkedList集合完成堆栈和队列 面试常问!!!
💡辉辉小贴士:那么在这,我们就一起来看看ArrayList和Vector的区别
💡辉辉小贴士:ArrayList和LinkedList的区别
顶级接口Collection
-
概念:
- 单列集合类的根接口,用于存储一系列符合某种规则的元素
-
方法【共性通用】
- public boolean add(E e): 把给定的对象添加到当前集合中 。
- public void clear() :清空集合中所有的元素。
- public boolean remove(E e): 把给定的对象在当前集合中删除。
- public boolean contains(E e): 判断当前集合中是否包含给定的对象。
- public boolean isEmpty(): 判断当前集合是否为空。
- public int size(): 返回集合中元素的个数。
- public Object[] toArray(): 把集合中的元素,存储到数组中
一.List集合的特点
- 有序【是指存进去的数据和拿出来的数据的顺序一致】
- 不唯一【即存进去的数据能够重复,可以重复添加同一个数据】
- 有下标
/** * list集合的特点: * 1.可以进行增删改查 * 2.可以重复添加相同的元素 * 3.有序(存取的顺序一致) * 4.有下标 */ //1.可以进行增删改查 List list = new ArrayList<>(); //增 list.add("wh"); list.add("xw"); list.add("xw"); System.out.println(list);//wh xw // //删 // list.remove(0); // System.out.println(list);//xw //改 list.set(0, "whxw"); System.out.println(list);//whxw, xw //查(打印输入【遍历】) System.out.println("打印的结果"+list); for (int i = 0; i < list.size(); i++) { System.out.println("fori的结果"+list.get(i)); } for (Object object : list) { System.out.println("foreach的结果"+object); } Iterator iterator = list.iterator(); while(iterator.hasNext()) { System.out.println("迭代器的结果"+iterator.next()); }
💡辉辉小贴士:由于List集合中的数据是不唯一,代表可以重复,那么怎么让它里面的元素不重复呢?
/** * arraylist的去重 */ //字符串 List list = new ArrayList<>();//存放初始数据的集合【别名A】 list.add("wh"); list.add("xw"); list.add("xw"); list.add("xw"); List list1 = new ArrayList<>();//存放去重之后的数据的集合【别名B】 for (Object object : list) {//遍历A if(!list1.contains(object)) {//如果B中A中的数据 list1.add(object);//就将这个数据加入到B中 } } System.out.println(list);//[wh, xw, xw, xw] System.out.println(list1);//[wh, xw] // 对象【在实体类中重写了equals方法】 List list = new ArrayList<>();// 存放初始数据的集合【别名A】 list.add(new Student(1, "zs")); list.add(new Student(1, "zs")); list.add(new Student(2, "ls")); System.out.println(list); // 输出的结果[Student [sid=1, sname=zs], Student [sid=1, sname=zs], Student [sid=2, // sname=ls]] List list1 = new ArrayList<>();// 存放去重之后的数据的集合【别名B】 for (Object object : list) {// 遍历A if (!list1.contains(object)) {// 如果B中A中的数据 list1.add(object);// 就将这个数据加入到B中 } } System.out.println(list1); // 输出的结果[Student [sid=1, sname=zs], Student [sid=1, sname=zs], Student [sid=2, // sname=ls]] // 重写equals方法 System.out.println(list1); // 输出的结果[Student [sid=1, sname=zs], Student [sid=2, sname=ls]] } package com.wh.test; public class Student { private int sid; private String sname; public Student() { // TODO Auto-generated constructor stub } public Student(int sid, String sname) { super(); this.sid = sid; this.sname = sname; } public int getSid() { return sid; } public void setSid(int sid) { this.sid = sid; } public String getSname() { return sname; } @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 (sid != other.sid) return false; if (sname == null) { if (other.sname != null) return false; } else if (!sname.equals(other.sname)) return false; return true; } public void setSname(String sname) { this.sname = sname; } @Override public String toString() { return "Student [sid=" + sid + ", sname=" + sname + "]"; } }
-
二.List集合的删除方式
-
for删除
-
正向删除(这种方法的结果是删的时候会出现删不干净的情况,虽然可以解决,但是不推荐此方法)
-
List list=new ArrayList();//创建集合 //添加几条示例数据 list.add("zs"); list.add("1s"); list.add("ww"); for (int i = 0; i < list.size(); i++) { list.remove(i); } System.out.println(list.size());//1
-
-
反向删除
-
-
迭代器删除
-
List list=new ArrayList();//创建集合 //添加几条示例数据 list.add("zs"); list.add("1s"); list.add("ww"); Iterator iterator = list.iterator();//创建迭代器 while(iterator.hasNext()){//遍历 iterator.next();//移动到下一个元素 iterator.remove();//移除元素 } System.out.println(list.size());//打印集合长度
💡辉辉小贴士:hasnext()和 next() 的区别
⚪hasnext()方法是判断这个集合的数据是否有下一个元素,如果有的话返回一个true,没有了则返回一个false.
⚪next()方法是将指针移动到下一个
-
三.List集合的子类
ArrayList集合
- 概念:
- 集合数据存储的结构是数组结构
- 特点
- 元素增删慢,查找快。【由于日常开发中使用最多的功能为查询数据、遍历数据,所以 ArrayList 是最常用的集合】
💡辉辉小贴士:那么为什么 ArrayList集合查找快呢?
因为ArrayList底层是用的数组存储 而数组的查询实际上是对引用地址的访问,不需要遍历
💡辉辉小贴士: ArrayList集合的扩容【代码演示】
- 首先, ArrayList集合的数据结构是一个数组,但是众所周知,数组的长度是固定的,可是我们却能够往ArrayList集合中加很多的数据,那么这是怎么完成的呢?
说到这,就不得不探究一下ArrayList集合的底层原理了
- ①利用空参创建集合时,在底层会创建一个默认长度为0的数组
- ②添加第一个元素时,底层会创建一个新的长度为10的数组
- 接下来看图解吧
- ③如果存进来第11个元素了,那么会数组会自动扩容为原来的1.5倍
- ④如果一次添加多个元素,1.5倍都无法放下,那么新创建的数组的长度就会等于实际存储的元素的大小(如果存进来100个元素,那么实际的长度就是100加上原来的元素)
- 接下来看图解吧
/** * arraylist的扩容 * */ List list = new ArrayList<>();//定义一个集合 for (int i = 0; i < 100; i++) {//遍历添加100条数据 list.add(i); System.out.println(i);//输入i getLen(list);//调用方法 } } public static void getLen(List lst){//拿到底层的数组的长度的方法 try { Field field =lst.getClass().getDeclaredField("elementData");拿到底层的数组 field.setAccessible(true); Object[] obj = (Object[]) field.get(lst); System.out.println("集合的大小是:"+obj.length);//输出集合的长度 } catch (Exception e) { e.printStackTrace(); } }
输出结果
由此,我们可以更加清楚的知道:①ArrayList集合的底层是长度为10的数组
②数组自动扩容为原来的1.5倍
LinkedList集合
- 概念:
- 集合数据存储的结构是链表结构【如图所示】
- 方便元素添加、删除的集合,查询慢,但如果操作的是首尾元素,速度也是极快的【本身多了很多直接操作首尾元素的特有API】
- LinkedList基于链表实现的,因此不存在容量不足的问题,所以没有扩容的方法
💡辉辉小贴士:什么是链表结构呢?
那让我们一起来看看它的底层原理吧!
- ①LinkedList是基于双向循环链表实现的,除了可以当作链表操作外,它还可以当作栈、队列和双端队列来使用。
- ②LinkedList同样是非线程安全的,只在单线程下适合使用。
- ③LinkedList实现了Serializable接口,因此它支持序列化,能够通过序列化传输。
- 集合数据存储的结构是链表结构【如图所示】
💡辉辉小贴士linked:怎么用LinkedList集合完成堆栈和队列 面试常问!!!
关于堆栈和队列的特点
/** * linkedlist完成堆栈【先进后出】 */ LinkedList list = new LinkedList<>(); list.add("a"); list.add("b"); list.add("c"); list.add("d"); Duizhan duizhan = new Duizhan(list); System.out.println(duizhan.pop()); System.out.println(duizhan.pop()); System.out.println(duizhan.pop()); System.out.println(duizhan.pop()); /** * 堆栈 */ package com.wh.test; import java.util.LinkedList; public class Duizhan { private LinkedList list =null; public Duizhan() { // TODO Auto-generated constructor stub } public Duizhan(LinkedList list) { super(); this.list = list; } public void add(String str){ list.add(str); } public Object pop() { return list.removeLast(); } }
/** * linkedlist完成队列【先进先出】 */ LinkedList list = new LinkedList<>(); list.add("a"); list.add("b"); list.add("c"); list.add("d"); DuiLie duiLie = new DuiLie(list); System.out.println(duiLie.pop()); System.out.println(duiLie.pop()); System.out.println(duiLie.pop()); System.out.println(duiLie.pop()); } /** * 队列 */ package com.wh.test; import java.util.LinkedList; public class DuiLie { private LinkedList list =null; public DuiLie() { // TODO Auto-generated constructor stub } public DuiLie(LinkedList list) { super(); this.list = list; } public void add(String str){ list.add(str); } public Object pop() { return list.remove(); } }
Vector集合
- 由于Vector集合不是我们常用的集合,因此在这就不做过多的赘述啦,有兴趣的可以自行到网上查阅相关资料哦。
💡辉辉小贴士:那么在这,我们就一起来看看ArrayList和Vector的区别
- 相同点
- 1、ArrayList和Vector都是用数组实现的
- 2、默认初始化大小都是10
- 不同点
- 1、Vector多线程是安全的,而ArrayList不是。Vector类中的方法很多有synchronized进行修饰,这样就导致了Vector在效率上无法与ArrayList相比;
- 2、两个都是采用的线性连续空间存储元素,但是当空间不足的时候,两个类的增加方式是不同的。(ArrayList每次存储时会检查空间大小,不够时会扩充为原来的1.5倍,Vector会扩充为原来空间的2倍)
💡辉辉小贴士: 由上述所看,好像Vector集合的优点还是很多的,那为什么Vector集合不是我们常用的集合呢?
让我们一起来看看原因吧
- Vector类的所有方法都是同步的(synchronized)。你可以使用两个线程安全的访问Vector对象。但是,如果你只用单个线程来访问Vector对象——这是更加常见的情况——那么你的代码将会在同步操作上浪费相当多的时间。相反,ArrayList类的方法不是同步的。因此现在的建议一般是在不需要同步时使用ArrayList而不是Vector
- 相同点
💡辉辉小贴士:ArrayList和LinkedList的区别
- 不同点
- 1、ArrayList底层实现是数组,而LinkedList是双向链表。
- 2、
- ArrayList查询快(下标)、增删改慢、
- LinkedList是查询慢(没有下标),但是在插入删除时效率比较高。(只影响前后的两个元素)
- 相同点
- 1、LinkedeList和ArrayList都实现了List接口。
- 2、ArrayList和LinkedList是两个集合类,用于存储一系列的对象引用(references)。
好啦,今天的分享就到这了,希望能够帮到你呢!😊😊