一、集合共有特点:
1.长度可变
2.能存储任意引用类型
3.具备很多对象的增删改查的方法
4.能存储基本数据类型的包装类
二、Collection
一、Collection接口
一、特点
1.有序
2.可重复
3.可排序
二、常用方法
1.添加
示例
//添加
c1.add(1);//添加元素
c1.add("张三");//添加元素
c1.add("李四");//添加元素
System.out.println(c1);
c2.add("王五");//添加元素
c2.add(true);//添加元素
c2.addAll(c1);//添加集合
System.out.println(c2);
2.删除
//删除
c2.remove(1);//删除元素
System.out.println(c2);
c2.removeAll(c1);//删除集合中的集合
System.out.println(c2);
c2.clear();//清空集合
System.out.println(c2);
3.修改
//修改:在Collection中并没有直接修改的功能,如果要修改,可以先删除后添加
4.遍历
//遍历
Object[] objects = c1.toArray();
for(Object o :objects){
System.out.print(o+" ");
}
5.判断功能
//判断功能
System.out.println(c1.contains(1));//判断集合是否包含某个元素
System.out.println(c2.containsAll(c1));//判断集合是否包含某个集合
System.out.println(c1.isEmpty());//判断集合是否为空
6.获取集合元素个数
System.out.println(c1.size());
System.out.println(c2.size());
7.获取两个集合中的交集元素,返回的结果是观察原集合是否发生了改变,true改变,false没有改变
Collection c3 = new ArrayList();
Collection c4 = new ArrayList();
c3.add(1);
c3.add(2);
c3.add(3);
c3.add(4);
c3.add(5);
c3.add(6);
c4.add(1);
c4.add(3);
c4.add(5);
c4.add(7);
c4.add(9);
boolean b = c3.retainAll(c4);
System.out.println(c3);
System.out.println(c4);
System.out.println(b);
完整代码:
package com.wedu.list;
import java.util.ArrayList;
import java.util.Collection;
/*增删改查*/
public class JavaTest {
public static void main(String[] args) {
//创建两个对象
Collection c1 = new ArrayList();
Collection c2 = new ArrayList();
//添加
c1.add(1);//添加元素
c1.add("张三");//添加元素
c1.add("李四");//添加元素
System.out.println(c1);
c2.add("王五");//添加元素
c2.add(true);//添加元素
c2.addAll(c1);//添加集合
System.out.println(c2);
//删除
c2.remove(1);//删除元素
System.out.println(c2);
c2.removeAll(c1);//删除集合中的集合
System.out.println(c2);
c2.clear();//清空集合
System.out.println(c2);
//修改:在Collection中并没有直接修改的功能,如果要修改,可以先删除后添加
//遍历
Object[] objects = c1.toArray();
for(Object o :objects){
System.out.print(o+" ");
}
System.out.println("=========================");
//判断功能
System.out.println(c1.contains(1));//判断集合是否包含某个元素
System.out.println(c2.containsAll(c1));//判断集合是否包含某个集合
System.out.println(c1.isEmpty());//判断集合是否为空
//获取集合元素个数
System.out.println(c1.size());
System.out.println(c2.size());
System.out.println("=========================");
//获取两个集合中的交集元素,返回的结果是观察原集合是否发生了改变,true改变,false没有改变
Collection c3 = new ArrayList();
Collection c4 = new ArrayList();
c3.add(1);
c3.add(2);
c3.add(3);
c3.add(4);
c3.add(5);
c3.add(6);
c4.add(1);
c4.add(3);
c4.add(5);
c4.add(7);
c4.add(9);
boolean b = c3.retainAll(c4);
System.out.println(c3);
System.out.println(c4);
System.out.println(b);
}
}
二、Iterator接口
所有的实现了Collection接口的集合类都有一个lterator()方法,该方法返回一个lterator接口对象,提供有集合数据遍历的方式
1、遍历集合元素
结合hasNext方法和next方法
package com.wedu.list;
import java.util.ArrayList;
import java.util.Iterator;
public class CollectionDemo04 {
public static void main(String[] args) {
ArrayList c1 = new ArrayList();
c1.add("张三1");
c1.add("张三2");
c1.add("张三3");
c1.add("张三4");
c1.add("张三5");
c1.add("张三6");
c1.add("张三7");
System.out.println(c1);
//通过Iterator迭代遍历集合
Iterator iterator = c1.iterator();
while (iterator.hasNext()){
Object o = iterator.next();//next:获取一个元素
System.out.println(o);
}
}
}
2、移除集合元素
通过循环的方式移除所有的元素,需要结合hasNext,next方法
package com.wedu.list;
import java.util.ArrayList;
import java.util.Iterator;
public class CollectionDemo06 {
public static void main(String[] args) {
ArrayList c1 = new ArrayList();
c1.add("张三1");
c1.add("张三2");
c1.add("张三3");
c1.add("张三4");
c1.add("张三5");
c1.add("张三6");
c1.add("张三7");
System.out.println(c1);
//通过Iterator迭代遍历集合
Iterator iterator = c1.iterator();
while (iterator.hasNext()){
iterator.next();
iterator.remove();
System.out.println(c1);
}
System.out.println(c1);
}
}
三、foreach循环
在Collection中可以用foreach来实现遍历集合元素
package com.wedu.list;
import java.util.ArrayList;
import java.util.Iterator;
public class CollectionDemo07 {
public static void main(String[] args) {
ArrayList c1 = new ArrayList();
c1.add("张三1");
c1.add("张三2");
c1.add("张三3");
c1.add("张三4");
c1.add("张三5");
c1.add("张三6");
c1.add("张三7");
System.out.println(c1);
//通过foreach来实现遍历集合
for(Object o :c1){
System.out.println(o);
}
}
}
三、List
一、概念
有序集合(序列)。该界面用户可以精准控制列表中每个元素的插入位置。用户可以通过整数索引(列表中的位置)访问元素,并搜素列表中的元素。
有序集合,List集合中有一个索引(下标),我们可以根据索引来操作集合中的元素
List接口是Collection的子接口
二、方法特点
获取一个List接口并存储元素
package com.wedu.list;
import java.util.ArrayList;
import java.util.List;
public class ListDemo01 {
public static void main(String[] args) {
List list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(null);
System.out.println(list);
}
}
1.添加
package com.wedu.list;
import java.util.ArrayList;
import java.util.List;
public class ListDemo01 {
public static void main(String[] args) {
List list1 = new ArrayList();//获取一个List接口
list1.add(1);
list1.add(2);//存储元素
list1.add(3);
list1.add(4);
list1.add(null);//添加null
System.out.println(list1);
list1.add(0,"张三");
System.out.println(list1);
List list2 = new ArrayList();
list2.add("小明");//添加一个元素
System.out.println(list2);
list2.add(1,"小李");//第二个位置添加一个元素
System.out.println(list2);
list2.add(0,list1);//把第一个位置加入List1
System.out.println(list2);
list2.addAll(1,list1);//把List1的元素插入到List2的第二个元素之后
System.out.println(list2);
}
}
====================================================
[1, 2, 3, 4, null]
[张三, 1, 2, 3, 4, null]
[小明]
[小明, 小李]
[[张三, 1, 2, 3, 4, null], 小明, 小李]
[[张三, 1, 2, 3, 4, null], 张三, 1, 2, 3, 4, null, 小明, 小李]
2.删除
(1)肯定具有Collection中的删除方法
(2)List中特有的删除方法:根据下标进行删除
package com.wedu.list;
import java.util.ArrayList;
import java.util.List;
public class ListDemo03 {
public static void main(String[] args) {
List list1 = new ArrayList();//获取一个List接口
list1.add(1);
list1.add(2);//存储元素
list1.add(3);
list1.add(4);
list1.add(null);//添加null
System.out.println(list1);
list1.remove(0);
System.out.println(list1);
}
}
3.修改
Collection修改不友好,但是List可以直接通过索引下标进行修改
package com.wedu.list;
import java.util.ArrayList;
import java.util.List;
public class ListDemo04 {
public static void main(String[] args) {
List list1 = new ArrayList();//获取一个List接口
list1.add(1);
list1.add(2);//存储元素
list1.add(3);
list1.add(4);
list1.add(null);//添加null
System.out.println(list1);
list1.set(0,666);
System.out.println(list1);
}
}
4、遍历获取集合中的相关元素
list遍历方式:
1、toArray
2、Iterator
3、foreach
4、普通for循环
5、ListIterator
可以使用Collection接口定义的方式及foreach循环
package com.wedu.list;
import java.util.ArrayList;
import java.util.List;
public class ListDemo05 {
public static void main(String[] args) {
List list1 = new ArrayList();//获取一个List接口
list1.add(1);
list1.add(2);//存储元素
list1.add(3);
list1.add(4);
list1.add(null);//添加null
System.out.println(list1);
list1.set(0,666);
System.out.println(list1);
//循环获取集合中的元素
for (int i=0;i<list1.size();i++){
System.out.print(list1.get(i)+" ");
}
}
}
迭代功能在list中的扩展
package com.wedu.list;
import java.util.ArrayList;
import java.util.List;
public class ListDemo06 {
public static void main(String[] args) {
List list1 = new ArrayList();//获取一个List接口
list1.add(1);
list1.add(2);//存储元素
list1.add(3);
list1.add(4);
list1.add("张三");
list1.add("李四");
list1.add(3);
System.out.println(list1);//输出集合
System.out.println(list1.indexOf(3));//从左到右获取集合中3的index位置
System.out.println(list1.lastIndexOf(3));//从右到左获取集合中3的index位置
System.out.println(list1.subList(2,4));//获取集合中2到4位置的数并生成新集合
}
}
三、Listlierator接口
1、Listlierator接口是Iterator接口的子接口,在Iterator正向迭代的基础上扩展了逆向迭代的操作
package com.wedu.list;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class ListDemo07 {
public static void main(String[] args) {
List list1 = new ArrayList();//获取一个List接口
list1.add(1);
list1.add(2);//存储元素
list1.add(3);
list1.add(4);
list1.add("张三");
list1.add("李四");
list1.add(3);
ListIterator li = list1.listIterator();
System.out.println(li.previousIndex()+" "+li.hasPrevious());//游标指向了第一个元素的左侧
while (li.hasNext()){//正向迭代 判断是否有下一个元素
System.out.println(li.nextIndex()+" : "+li.next());
}
System.out.println(li.previousIndex()+" "+li.hasPrevious());//游标指向了最后一个元素的右侧
System.out.println("==================================================");
while(li.hasPrevious()){
System.out.println(li.previousIndex()+ " : "+li.previous());
}
}
}
/
2、List去除重复元素
方式 一·:创建一个新的集合来存储去除重复后的元素
package com.wedu.list;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class ListDemo08 {
public static void main(String[] args) {
List list1 = new ArrayList();//获取一个List接口
list1.add(1);
list1.add(2);//存储元素
list1.add(3);
list1.add(4);
list1.add("张三");
list1.add("李四");
list1.add(3);
System.out.println(list1);
List list2 = new ArrayList();
for (Object o : list1){
if(!list2.contains(o)){
list2.add(o);
}
}
System.out.println(list2);
}
}
方式二:在原有基础上使用选择排序的思想来去除重复元素(只有一个重复元素时)
package com.wedu.list;
import java.util.ArrayList;
import java.util.List;
public class ListDemo09 {
public static void main(String[] args) {
List list1 = new ArrayList();//获取一个List接口
list1.add(1);
list1.add(2);//存储元素
list1.add(3);
list1.add(4);
list1.add("张三");
list1.add("李四");
list1.add(3);
System.out.println(list1);
for(int i = 0;i< list1.size()-1;i++){
for(int j = i+1;j< list1.size();j++){
if(list1.get(i).equals(list1.get(j))){
list1.remove(j);
}
}
}
System.out.println(list1);
}
}
方式三:在原有基础上使用选择排序的思想来去除重复元素(一个元素多次重复时)【面试题】
package com.wedu.list;
import java.util.ArrayList;
import java.util.List;
public class ListDemo09 {
public static void main(String[] args) {
List list1 = new ArrayList();//获取一个List接口
list1.add(1);
list1.add(3);//存储元素
list1.add(3);
list1.add(3);
list1.add("张三");
list1.add("李四");
list1.add(3);
System.out.println(list1);
for(int i = 0;i< list1.size()-1;i++){
for(int j = i+1;j< list1.size();j++){
if(list1.get(i).equals(list1.get(j))){
list1.remove(j);
j--;
}
}
}
System.out.println(list1);
}
}
四、List接口的相关实现类
1、ArrayLIst
1、ArrayLIst
可调整大小的数组实现LIst接口。实现所有可选列表操作,并允许所有元素,包括null,
特点:
1.底层的数据结构是数组。
2、能存储null值
3、线程效率高,不安全
4底层是数组结构,查询和修改的效率高,增加删除的效率低
5、有索引,方便检索
6、元素可重复,可以通过选择排序法去重
7、不可以排序
注:ArrayList中的常用方法全部来自父类Collection、List、Object
案例:
存储多个员工信息(工号、姓名、年龄、入职时间),逐条打印员工姓名,并输出员工个数,使用ArrayList存储数据,元素个数不确定,要求获得元素实际个数,按照存储顺序获取并打印元素信息
package com.wedu.ListTest.Demo01;
/*
存储多个员工信息(工号、姓名、年龄、入职时间),逐条打印员工姓名,并输出员工个数,
使用ArrayList存储数据,元素个数不确定,要求获得元素实际个数,按照存储顺序获取并打印元素信息
* */
import java.util.ArrayList;
import java.util.Date;
public class Test01 {
public static void main(String[] args) {
ArrayList list = new ArrayList();//创建ArrayList集合
for(int i = 0;i<10;i++){//遍历创建10个对象
Employee e = new Employee("emp"+i,"张三"+i,10+i,new Date());
list.add(e);//将对象加入集合
}
System.out.println(list);
for(Object o:list){
if(o instanceof Employee){//检查当前遍历到的对象o是否是Employee类的实例。
Employee e = (Employee) o;//如果o是Employee类的实例,那么这里会将o强制类型转换为Employee类型,并将其赋值给新的变量e。
System.out.println(e);
}
}
System.out.println("员工个数是"+list.size());
}
static class Employee{
private String empNo;
private String empName;
private Integer age;
private Date entryDate;
public Employee(String empNo, String empName, Integer age) {
this.empNo = empNo;
this.empName = empName;
this.age = age;
}
public Employee(String empNo, String empName, Integer age, Date entryDate) {
this(empNo,empName,age);
this.entryDate = entryDate;
}
public String getEmpNo() {
return empNo;
}
public void setEmpNo(String empNo) {
this.empNo = empNo;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Employee{" +
"empNo='" + empNo + '\'' +
", empName='" + empName + '\'' +
", age=" + age +
", entryDate=" + entryDate +
'}';
}
}
}
结果:
[Employee{empNo='emp0', empName='张三0', age=10, entryDate=Mon Aug 26 11:08:34 CST 2024},
Employee{empNo='emp1', empName='张三1', age=11, entryDate=Mon Aug 26 11:08:34 CST 2024},
Employee{empNo='emp2', empName='张三2', age=12, entryDate=Mon Aug 26 11:08:34 CST 2024},
Employee{empNo='emp3', empName='张三3', age=13, entryDate=Mon Aug 26 11:08:34 CST 2024},
Employee{empNo='emp4', empName='张三4', age=14, entryDate=Mon Aug 26 11:08:34 CST 2024}, Employee{empNo='emp5',empName='张三5', age=15, entryDate=Mon Aug 26 11:08:34 CST 2024},
Employee{empNo='emp6', empName='张三6', age=16, entryDate=Mon Aug 26 11:08:34 CST 2024},
Employee{empNo='emp7', empName='张三7', age=17, entryDate=Mon Aug 26 11:08:34 CST 2024},
Employee{empNo='emp8', empName='张三8', age=18, entryDate=Mon Aug 26 11:08:34 CST 2024},
Employee{empNo='emp9', empName='张三9', age=19, entryDate=Mon Aug 26 11:08:34 CST 2024}]
Employee{empNo='emp0', empName='张三0', age=10, entryDate=Mon Aug 26 11:08:34 CST 2024}
Employee{empNo='emp1', empName='张三1', age=11, entryDate=Mon Aug 26 11:08:34 CST 2024}
Employee{empNo='emp2', empName='张三2', age=12, entryDate=Mon Aug 26 11:08:34 CST 2024}
Employee{empNo='emp3', empName='张三3', age=13, entryDate=Mon Aug 26 11:08:34 CST 2024}
Employee{empNo='emp4', empName='张三4', age=14, entryDate=Mon Aug 26 11:08:34 CST 2024}
Employee{empNo='emp5', empName='张三5', age=15, entryDate=Mon Aug 26 11:08:34 CST 2024}
Employee{empNo='emp6', empName='张三6', age=16, entryDate=Mon Aug 26 11:08:34 CST 2024}
Employee{empNo='emp7', empName='张三7', age=17, entryDate=Mon Aug 26 11:08:34 CST 2024}
Employee{empNo='emp8', empName='张三8', age=18, entryDate=Mon Aug 26 11:08:34 CST 2024}
Employee{empNo='emp9', empName='张三9', age=19, entryDate=Mon Aug 26 11:08:34 CST 2024}
员工个数是10
2、ArrayLIst原理分析
ArrayLIst的本质就是动态数据,动态扩容。
ArrayList集合练习:
(1)创建一个Person类,添加属性:name,age;封装这些属性并分别设置各个属性的方法。
(2)根据用户输入的对象个数创建Person对象,接收用户在控制台上输入的每个对象的信息。
(注意,将有些Person对象的名字和年龄设置相同)
(3)创建一个ArrayList集合,将Person对象添加到ArrayList集合中。
(4)使用迭代器迭代输出该List集合
(5)写一个方法,可以去除ArrayList集合中重复的Person对象。
姓名和年龄相同视为重复的Person对象
* */
Person类
package com.wedu.arrayList;
public class Person {
private String name;
private Integer age;
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
测试:
package com.wedu.arrayList;
import java.util.ArrayList;
import java.util.ListIterator;
import java.util.Scanner;
/*
ArrayList集合练习:
(1)创建一个Person类,添加属性:name,age;封装这些属性并分别设置各个属性的方法。
(2)根据用户输入的对象个数创建Person对象,接收用户在控制台上输入的每个对象的信息。
(注意,将有些Person对象的名字和年龄设置相同)
(3)创建一个ArrayList集合,将Person对象添加到ArrayList集合中。
(4)使用迭代器迭代输出该List集合
(5)写一个方法,可以去除ArrayList集合中重复的Person对象。
姓名和年龄相同视为重复的Person对象
* */
public class ArrayListDemo04 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("请输入Person对象个数: ");
int number = in.nextInt();
System.out.println("Person的姓名");
String name = in.next();
System.out.println("Person的年龄");
Integer age = in.nextInt();
ArrayList list = new ArrayList();
for(int i = 0;i<number;i++){
Person person = new Person(name,age);
list.add(person);
}
printIterator(list);//使用迭代器,输出集合。快捷键:Alt+Enter提取方法
removeRepetitionElement(list);//移除重复元素
System.out.println("======================================================");
printIterator(list);//再次使用迭代器,输出集合。//使用迭代器,输出集合。
}
public static void removeRepetitionElement(ArrayList list){
for (int i = 0;i<list.size()-1;i++){
for (int j = i+1;j<list.size();j++){
Person p1 = (Person) list.get(i);
Person p2 = (Person) list.get(j);
if(p1.getName().equals(p2.getName())&&p1.getAge()==p2.getAge()){
list.remove(j);
j--;
}
}
}
}
public static void printIterator(ArrayList list) {
ListIterator listIterator = list.listIterator();
while(listIterator.hasNext()){
Object next = listIterator.next();
if(next instanceof Person){
Person p = (Person) next;
System.out.println(p);
}
}
}
}
输出结果:
Person{name='张三', age=18}
Person{name='张三', age=18}
Person{name='张三', age=18}
Person{name='张三', age=18}
Person{name='张三', age=18}
======================================================
Person{name='张三', age=18}
2、Vector
概述
Vector类实现了可扩展的对象数组。像数组一样,它包含可以使用整数索引访问的组件,但是Vector的大小可以根据需要增长或者缩小,以适应在创建Vector之后添加和删除项目。
常用·方法:
示例代码:
package com.wedu.vector;
import java.util.Enumeration;
import java.util.Vector;
public class VectorDemo01 {
public static void main(String[] args) {
Vector v = new Vector();
v.add("a");
v.addElement("b");
v.add("c");
v.add("d");
System.out.println(v);
v.removeElementAt(3);
v.set(1,"c");
System.out.println(v);
Enumeration elements = v.elements();
while(elements.hasMoreElements()){
System.out.println(elements.nextElement());
}
System.out.println("=================================");
System.out.println(v);
}
}
输出结果:
[a, b, c, d]
[a, c, c]
a
c
c
=================================
[a, c, c]
特点:
1、底层数据结构是数组
2、有索引,能够方便检索
3、增加和删除的效率低。
4、线程安全,效率低
5.能够存储null
6、元素可重复
7、不可以排序
3、Stack
概念:
-
Stack
类代表最先进先出(LIFO)堆栈的对象。它扩展了类别Vector
与五个操作,允许一个向量被视为堆栈。设置在通常的push
和pop
操作,以及作为一种方法来peek
在堆栈,以测试堆栈是否为empty
的方法,以及向search
在栈中的项目的方法在顶部项目和发现多远它是从顶部。当首次创建堆栈时,它不包含任何项目。
栈的特点:
1、基于栈结构的集合,后进先出
2、Stack类是Vector的子类,所有该类也是线程安全的,效率低。
常用方法:
-
-
boolean
empty()
测试此堆栈是否为空。E
peek()
查看此堆栈顶部的对象,而不从堆栈中删除它。E
pop()
删除此堆栈顶部的对象,并将该对象作为此函数的值返回。E
push(E item)
将项目推送到此堆栈的顶部。int
search(Object o)
返回一个对象在此堆栈上的基于1的位置。
-
注意:如果栈中的元素为空,那么尝试弹栈(pop方法),将会抛出EmptyStackException
package com.wedu.stack;
import java.util.Stack;
public class StackDemo1 {
public static void main(String[] args) {
Stack s = new Stack();
s.push("a");
s.push("b");
s.push("c");
s.push("d");
s.push("e");
s.push("f");
System.out.println(s);
while (s.isEmpty()) {
System.out.println(s.peek());
System.out.println(s.pop());
}
System.out.println(s.peek());
System.out.println(s.pop());
System.out.println(s.peek());
System.out.println(s.pop());
s.peek();
}
}
4、Queue
概念:
- 设计用于在处理之前保留元素的集合。 除了基本的
Collection
操作之外,队列还提供额外的插入,提取和检查操作。 这些方法中的每一种都有两种形式:如果操作失败,则抛出一个异常,另一种返回一个特殊值(null
或false
,具体取决于操作)。 插入操作的后一种形式专门设计用于容量限制的Queue
实现; 在大多数实现中,插入操作不能失败。
特点:
1、该接口是队列的根接口,先进先出
2、该接口提供队列相关的两种形式的方法,一种抛异常,一种返回一个特殊值(null或者false)
抛出异常 | 返回特殊值 | |
---|---|---|
插入 | add(e) | offer(e) |
移除 | remove() | poll() |
检查 | element() | peek() |
实现代码
package com.wedu.queue;
import java.util.ArrayDeque;
public class QueueDemo1 {
public static void main(String[] args) {
ArrayDeque q = new ArrayDeque(2);
System.out.println(q.add("a"));
System.out.println(q.add("b"));
System.out.println(q.offer("c"));
System.out.println(q.offer("d"));
// for(int i = 0;i<15;i++){
// System.out.println(q.offer("f"));
// }
System.out.println(q);
// q.remove();
q.poll();
System.out.println(q);
// q.remove();
q.poll();
System.out.println(q);
// q.remove();
q.poll();
System.out.println(q);
System.out.println(q.element());
System.out.println(q.peek());
}
}
5、Deque
概述
一个线性collection,支持在两端插入和移除元素。名称deque是"doubleendedqueue(双端队列)“的缩写,通常读为"deck”。大多数Dequer实现对于它们能够包含的元素数没有固定限制,但此接口既支持有容量限制的双端队列,也支持没有固定大小限制的双端队列。
特点
1.Deque是一个Queue的子接口,是一个双端队列,支持在两端插入和移除元素
2.deque支持索引值直接存取。
3.Deque头部和尾部添加或移除元素都非常快速。但是在中部安插元素或移除元素比较费时。
4.插入、删除、获取操作支持两种形式:快速失败和返回null或true/false
5.不推荐插入nul/元素,null作为特定返回值表示队列为空
常用方法
第一个元素(头部) | 最后一个元素(尾部) | |||
---|---|---|---|---|
拋出异常 | 特殊值 | 拋出异常 | 特殊值 | |
插入 | addFirst(e) | offerFirst(g) | addLast(e) | offerLast(g) |
移除 | removeFirst() | pollFirst() | removelast() | pollLast() |
检查 | getFirst() | peekFirst() | getLast() | peekLast() |
2、双向队列操作
插入元素
addFirst():向队头插入元素,如果元素为null,则发生空指针异常
addLast():向队尾插入元素,如果为空,则发生空指针异常
offerFirst():向队头插入元素,如果插入成功返回true,否则返回
falseofferLast():向队尾插入元素,如果插入成功返回true,否则返回false
移除元素
removeFirst();返回并移除队头元素,如果该元素是null,则发生NoSuchElementException
removeLast():返回并移除队尾元素,如果该元素是null,则发生NoSuchElementException
pollFirst():返回并移除队头元素,如果队列无元素,则返回null•
pollLast():返回并移除队尾元素,如果队列无元素,则返回null
获取元素
getFirst():获取队头元素但不移除,如果队列无元素,则发生NoSuchElementException•
getLast():获取队尾元素但不移除,如果队列无元素,则发生NoSuchElementException•
peekFirst():获取队头元素但不移除,如果队列无元素,则返回null
•peekLast():获取队尾元素但不移除,如果队列无元素,则返回null
栈操作
pop():弹出栈中元素,也就是返回并移除队头元素,等价于removeFirst(),如果队列无元素,则发生NoSuchElementException
push():向栈中压入元素,也就是向队头增加元素,等价于addFirst(),如果元素为null,则发生NoSuchElementException,如果栈空间受到限制,则发生llegalStateException
引用场景
1.满足FIFO场景时
2.满足LIFO场景时,曾经在解析XML按标签时使用过栈这种数据结构,但是却选择Stack类,如果在进行栈选型时,更推荐使用Deque类,应为Stack是线程同步
6、ArrayDeque
概述
Deque接口的大小可变数组的实现。数组双端队列没有容量限制;它们可根据需要增加以支持使用。它们不是线程安全的;在没有外部同步时,它们不支持多个线程的并发访问,禁止nulL元素,此类很可能在用作堆栈时快于Stack,在用作队列时快干LinkedList。
特点
1.ArrayDeque是Deque接口的一种具体实现,是依赖于可变数组来实现的
2.ArrayDeque没有容量限制,可根据需求自动进行扩容
3.ArrayDeque不支持值为null的元素。
4.ArrayDeque可以作为栈来使用,效率要高于Stack5.ArrayDeque也可以作为队列来使用,效率相较于基于双向链表的LinkedList也要更好一些
7、LinkedList
链表结构
特点
1、灵活的空间要求,存储空间不要求连续
2、不支持下标访问、支持顺序遍历
3、针对增删效率会高一些,只和操作节点的前后有关系、无需移动元素
1、LinkedList
-
双链表实现了
List
和Deque
接口。实现所有可选列表操作,并允许所有元素(包括null
)。所有的操作都能像双向列表一样预期。 索引到列表中的操作将从开始或结束遍历列表,以更接近指定的索引为准。
请注意,此实现不同步。 如果多个线程同时访问链接列表,并且至少有一个线程在结构上修改列表,则必须在外部进行同步。 (结构修改是添加或删除一个或多个元素的任何操作;仅设置元素的值不是结构修改。)这通常通过在自然封装列表的对象上进行同步来实现。 如果没有这样的对象存在,列表应该使用
Collections.synchronizedList
方法“包装”。 这最好在创建时完成,以防止意外的不同步访问列表:特点:
1LinkedList底层的数据结构是一个双向链表,元素有序可重复
2.LinkedList在实现数据的添加和删除效率高,查询和修改效率低,顺序访问会非常高效,而随机访问效率会比较低
3.LinkedList实现List接口,支持使用索引访问元素
4.LinkedList实现Deque接口,所以LinkedList也可以当做双端队列使用
5.LinkedList是线程不安全的效率高
泛型
概念
在编译时就确定类型的一种技术,是一种将引用类型当做参数传递的参数化类型,在编译时就确定了集合存储的元素类型
格式:<数据类型>这里面的类型必须是引用类型:例
List<String> list = new ArrayList();
为什么要使用泛型:集合中是可以存储任意的引用类型数据的,如果同一个集合中存储的数据类型不一致,那么我在操作数据的时候有可能出现数据类型安全问题,这时我们可以通过泛型来解决这个问题。
package com.wedu.genericity;
import java.util.ArrayList;
import java.util.List;
public class GenericityDemo02 {
public static void main(String[] args) {
List<String> list = new ArrayList();
list.add("张三1");
list.add("张三2");
list.add("张三3");
for(int i = 0;i <list.size();i++){
String s = list.get(i);
System.out.println(s);
}
System.out.println("==========================");
for (String s:list){
System.out.println(s);
}
}
}
好处:
1,、提高了程序的安全性
2、消除了黄色警告线(Eclipse中)
3、在编译时期将类型确定,减少了不必要的强转代码
改。)这通常通过在自然封装列表的对象上进行同步来实现。 如果没有这样的对象存在,列表应该使用Collections.synchronizedList
方法“包装”。 这最好在创建时完成,以防止意外的不同步访问列表:
特点:
1LinkedList底层的数据结构是一个双向链表,元素有序可重复
2.LinkedList在实现数据的添加和删除效率高,查询和修改效率低,顺序访问会非常高效,而随机访问效率会比较低
3.LinkedList实现List接口,支持使用索引访问元素
4.LinkedList实现Deque接口,所以LinkedList也可以当做双端队列使用
5.LinkedList是线程不安全的效率高
泛型
概念
在编译时就确定类型的一种技术,是一种将引用类型当做参数传递的参数化类型,在编译时就确定了集合存储的元素类型
格式:<数据类型>这里面的类型必须是引用类型:例
List<String> list = new ArrayList();
为什么要使用泛型:集合中是可以存储任意的引用类型数据的,如果同一个集合中存储的数据类型不一致,那么我在操作数据的时候有可能出现数据类型安全问题,这时我们可以通过泛型来解决这个问题。
package com.wedu.genericity;
import java.util.ArrayList;
import java.util.List;
public class GenericityDemo02 {
public static void main(String[] args) {
List<String> list = new ArrayList();
list.add("张三1");
list.add("张三2");
list.add("张三3");
for(int i = 0;i <list.size();i++){
String s = list.get(i);
System.out.println(s);
}
System.out.println("==========================");
for (String s:list){
System.out.println(s);
}
}
}
好处:
1,、提高了程序的安全性
2、消除了黄色警告线(Eclipse中)
3、在编译时期将类型确定,减少了不必要的强转代码