集合
1.含义
- 集合是Java API自己提供的一系列的类,可以作用于动态存放多个对象(集合只能存对象)
- 集合与数组的不同:
- 集合
- 集合是大小可变的序列
- 元素类型可以不受限定
- 只要是引用类型
- 集合不能存放基本数据类型,但可以放基本数据类型的包装类
- 数组:
- 数组长度固定
- 数组可以存储基本数据类型和引用类型
- 集合类全部支持泛型,是一种数据安全的用法
集合框架图
Java的集合框架从整体上可以分为两大家族
- Collection(接口)家族,该接口下的所有子孙均存储的是单一对象。Add(s)
- Map(接口)家族,该接口下的所有子孙均存储的是key-value(键值对)形式的数据。 Put(key,value)
另外还有三个分支,均是为上面两个大家族服务的
- Iterator(迭代器)家族。只要用于遍历Collection接口及其子类而设计
- Comparator(比较器),在集合中存储对象的时候,用于对象之间的比较
- Collections是工具类。注意:该类名带了个s,一般就表示工具类。里面提供了N多静态方法,来对Collection集合进行比较
List:有序(跟录入的顺序一致)可以重复 有下标
Set:无序(跟录入的顺序不一致,并不是随机的,而是由hash值+散列算法来决定的),不可以重复 没有下标
List list=new ArrayList();
List.add();
Set set=new HashSet();
Set.add();
Collection接口含有List和Set两个子接口
常用方法:
- int size();返回此Collection中的元素
- boolean i是Empty();判断此collection是否包含元素
- boolean contains(Object obj);判断此collection是否包含指定的元素。
- boolean contains(Collection c);判断此collection是否包含指定collection中的所有元素
- boolean add(Object element);向此collection中添加元素
- boolean addAll(Collection c);将指定collection中的所有元素添加到此collection中
- boolean remove(Object element);从此colletion中移除指定的元素
- boolean removeAll(Collection c);移除此collection中那些也包含在指定colletion中的所有元素
- void clear();移除collection中所有的元素
- boolean retainAll(Collection c);仅保留此collection中那些也包含在指定collection的元素
- Iterator iterator();返回在此collection的元素上进行迭代的迭代器
- Object[] toArray();把此collection转成数组
List接口相比于Collection接口的新增方法
新增的几个实用方法:
- public Object get(int index) //根据下标,返回列表中的元素
- public Object add(int index,Object element) //在列表的指定位置插入指定的元素,将当前处于该位置的元素(如果有的话)和所有后续元素向右移动
- public Object set(int index,Object element)// 用指定元素替换指定位置的元素
- public Object remove(int index) //移除表中指定位置的元素
- 注意:list集合中的元素被索引与数组中的元素一样,均是从0开始
List接口
特点:有序可重复有下标(因为List接口中添加许多针对下操作的方法)
实现类:
ArrayList
public class Test{ public static void main(Strin[] args){ ArrayList list=new ArrayList(); //添加元素 list.add("字符串"); list.add(100);//Integer.valueOf(100); list.add(123.123);//Double.valuOf(123.123); } }
LinkedList
代码1:
public class Test01{ public static void main(String [] args){ /** 知识点:使用Linkedlist方法+泛型 泛型:数据安全的作法,规定集合应该储存什么样的数据类型 */ LinkedList<String> list=new LinkedList<>(); //添加元素 list.add("荣十一"); list.add("沝"); list.add("沝心"); //获取元素的个数 int size=list.size(); System.out.println("获取元素的个数:"+size); //设置指定下标上的元素 list.set(0,"小郑"); //获取指定下标上的元素 String element=list.get(0); System.out.println("获取指定下标的元素:"+element); //在指定下标上插入元素 list.add(1,"小张"); LinkedList<String> newlist1=new LinkedList<>(); Collections.addAll(newlist,"aaa","bbb","ccc");//利用集合工具进行批量添加 list.addAll(newlist1);//将新集合中所有的元素添加到指定的集合的末尾 LinkedList<String> newList2=new LinkedList<>(); Collections.addAll(newList2,"ddd","eee","fff");//利用集合工具类批量添加 list.addAll(3,newList2);//将新集合中所有的元素添加到指定集合上指定的下标 //清楚集合中所有的元素 list.clear(); System.out.println("判断集合中是否包含某个元素"+list.contains("小张")); LinkedList<String> newList3=new LinkedList<>(); Collections.addAll(newList3,"eee","fff","ddd");//利用集合工具类进行批量添加 System.out.println("判断集合中是否包含某个集合中所有的元素:"+list.containsAll(newList3)); int index=list.indexOf("沝"); System.out.println("获取元素在集合中的下标"+index); boolean empty =list.isEmpty();//有元素则---false 无元素则---ture System.out.prinntln("判断集合中是否没有该元素:"+empty);//false //删除 list.remove(3);//依据下标删除元素 list.remove("eee");//依据元素删除元素 //删除---交集 LinkedList<String> newList4=new linkedList<>(); Collections.addAll(newList4,"fff","aaa","bbb");//利用集合的工具类进行批量添加 list.addAll(newList4); //保留集合 LinkedList<String> newList5=new LinkedList<>(); Collections.addAll(newList,"榮十一","小雅","小惠"); list.retainAll(newList5); //替换指定下标上的元素 list.set(4,"桜儿"); //获取开始下标到结束下标(不包含)的元素,并返回新的集合 List<String> subList=list.subList(1,5); //将集合转换为数组 Object[] array=subList.toArray(); System.out.println(Arrays.toString(array)); System.out.println("-----------"); //遍历----for for(int i=0;i<list.size();i++){ System.out.println(list.get(i)); } System.out.println("-----------"); //遍历---foreach for(String e:list){ System.out.println(e); } System.out.println("--------------"); //遍历-----Iterator迭代器 Iterator<String> it=list.iterator();//获取Iterator迭代器对象 while(it.hashNext()){//判断是否有可以迭代的元素 String e=it.next();//返回下一个元素 System.out.println(e); } System.out.println("-------------"); //遍历-------ListIterator迭代器 ListIterator<String> listIterator=list.listIterator();//获取ListIterator迭代器对象 while(listIterator.hashNext()){//判断是否有可以迭代的对象 String e=listIterator.next();//返回下一个元素 System.out.println(e); } } }
public class Test{ public static void main(String[] args){ /** 知识点:LinkedList 队列模式 特点:先进先出 */ LinkedList<String> list=new LinkedList<>(); list.add("xxx"); list.add("yyy"); list.add("zzz"); while(!list.isEmpty()){ //删除第一个元素,并返回 String element=list.removeFist(); System.out.println(element); } System.out.println("集合中元素的个数:"+list.size()); } }
public class Test{ public static void main(String[] args){ /** 知识点:LinkedList 栈模式 特点:先进后出 */ LinekList<String> list=new LinkedList<>(); list.add("xxx"); list.add("yyy"); list.add("ddd"); list.add("zzz"); while(!list.isEmpty()){ //删除最后一个元素,并返回 String element=list.removeLast(); System.out.println(element); }System.out.println("集合中的元素个数:"+list.size()); } }
Vector
public class Test{ public static void main(String[] args){ /** 知识点:使用Vector实现List接口的方法 了解:Vector是元老级别的集合类,在JDK1.0开始使用。JDK1.2开始才推出集合框架的概念,考虑到党史很多程序员习惯使用Vector,就让Vector多实现了List接口,这样将其保留下来 */ Vector<String> list=new Vector<>(); //添加元素 list.add("aaa"); list.add("bbb"); list.add("ccc"); list.add("ddd"); //获取元素的个数 int size=list.size(); System.out.println("获取元素的个数:"+size); //遍历--for for(String elements:list){ System.out.println(list.get(i)); } } } //与上面代码1一致,只需要将LinkeList改为Vector即可,理由:都是继承父类list的方法
public class Test{ public static void main(String[] args){ //知识点:Vector的老方法 Vector<String> v=new Vector<>(); //添加元素 list.add("aaa"); list.add("bbb"); list.add("ccc"); list.add("ddd"); //删除 v.removeElement("ccc");//根据元素删除元素 v.removeElement(3);//根据下标删除元素 //遍历 Enumeration<String> element=v.elements(); while(elements.hasMoreElements()){ String nextElement=element.nextElement(); System.out.println(nextElement); } } }
Stack
public class Test{ public static void main(String[] args){ /** 知识点:Stack 特点:栈模式 ---先进后出 */ Stack <String> stack=new Stack<>(); //添加元素--将元素压入栈顶 stack.push("榮1"); stack.push("榮2"); stack.push("榮3"); stack.push("榮4"); System.out.println("距离栈顶的位置(从1开始):"+stack.search("榮2")); while(!stack.empty()){ //获取栈顶第一个元素,并返回 //String element=stack.peek(); //删除栈顶第一个元素,并返回 String element=stack.pop(); System.out.println(element); } System.out.println(stack.size()); } }
Set接口
接口:无序且不可重复
实现类:
- HashSet
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
public class Test01{
public static void main(String[] args){
/**
知识点:使用HashSet方法
特点:去重+无序
*/
HashSet<String> set=new HashSet<>();
//添加
set.add("榮1");
set.add("榮2");
set.add("榮3");
set.add("榮5");
//获取元素的个数
int size=set.size();
System.out.println("获取的元素个数:"+size);
HashSet<String> newSet1=new HashSet<>();
Collections.addAll(newSet1,"沝","沝心");
set.addAll(newSet1);//将新集合中所有元素添加到指定集合的末尾
//清空集合中的所有元素
//set.clear();
System.out.println("判断集合中是否包含某个元素"+set.contains("榮2"));
HashSet<String> newSet2=new HashSet<>();
Collections.addAll(newSet2,"榮沝","榮沝心");
System.out.println("判断集合中是否包含某个元素:"+set.containsAll(newSet2));
boolean empty=set.isEmpty();//有元素--false 没有元素--true
System.out.println("判断集合中是否没有元素:"+empty);
//删除
set.remove("榮2");
//删除-交集
HashSet<String> newSet3=new HashSet<>();
Collections.addAll(newSet3,"榮5","沝心","榮沝心");
set.removeAll(newSet3);
//保留交集
HashSet<String> newSet4=new HashSet<>();
Collections.addAll(newSet4,"榮1","榮沝","沝");
set.retainAll(newSet4);
//将集合转欸数组
Object [] array=set.toArray();
System.out.println(Arrays.toString(array));
System.out.println("---------------");
//遍历----foreach
for(String element:set){
System.out.println(element);
}
System.out.println("--------------");
//遍历----Iterator迭代器
Iterator<String> it=set.iterator();//获取Iterator迭代器对象
while(it.hasNext()){//判断是否有可以迭代的元素
String e=it.next();//返回下一个元素
System.out.println(e);
}
}
}
LinkedHashSet
public class Test{ public static void main(String[] args){ /** 知识点:使用LinkedHashSet方法 特点:去重+有序 */ LinkedHashSet<String> set=new LinkedHashSet<>(); //添加 stack.add("榮1"); stack.add("榮2"); stack.add("榮3"); stack.add("榮5"); //获取元素的个数 int size=list.size(); System.out.println("获取的元素个数:"+size); LinkedHashSet<String> newSet1=new LinkedHashSet<>(); Collections.addAll(newSet1,"沝","沝心"); set.addAll(newSet1);//将新集合中所有元素添加到指定集合的末尾 //清空集合中的所有元素 //set.clear(); System.out.println("判断集合中是否包含某个元素"+set.catains("榮2")); LinkedHashSet<String> newSet2=new LinkedHashSet<>(); Collections.addAll(newSet2,"榮沝","榮沝心"); System.out.println("判断集合中是否包含某个元素:"+set.containsAll(newSet2)); boolean empty=set.isEmpty();//有元素--false 没有元素--true Sytem.out.println("判断集合中是否没有元素:"+empty); //删除 set.remove("榮2"); //删除-交集 LinkedHashSet<String> newSet3=new LinkedHashSet<>(); Collections.addAll(newSet3,"榮5","沝心","榮沝心"); set.removeAll(newSet3); //保留交集 LinkedHashSet<String> newSet4=new LinkedHashSet<>(); Collections.addAll(newSet4,"榮1","榮沝","沝"); set.retainAll(newSet4); //将集合转欸数组 Object [] array=set.toArray(); System.out.println(Arrays.toString(array)); System.out.println("---------------"); //遍历----foreach for(String element:set){ System.out.println(element); } System.out.println("--------------"); //遍历----Iterator迭代器 Iterator<String> it=set.iterator();//获取Iterator迭代器对象 while(it.hashNext()){//判断是否有可以迭代的元素 String e=it.next();//返回下一个元素 System.out.println(e); } } }
TreeSet
同样TreeSet也是继承set的,也有以上的方法
public class Test{ public static void main(String[] args){ /** 知识点:TreeSet排序 需求:创建两个TreeSet对象,分别存Integer、String,感受排序 TreeSet存Integer:数字排序 TreeSET存String: 字典排序 */ TreeSet<String> set1=new TreeSet<>(); //添加元素 set1.add(5);//Integer.valueOf(5); set1.add(1);//Integer.valueOf(1); set1.add(3);//Integer.valueOf(3); set1.add(4);//Integer.valueOf(4); set1.add(2);//Integer.valueOf(2); //遍历-----foreach for(Integer integer:set1){ System.out.println(integer); } TreeSet<String> set2=new TreeSet<>(); set.add("c"); set.add("d"); set.add("a"); set.add("b"); for(String string:set2){ System.out.println(string); } } }
public class Test{ public static void main(String[] args){ /** 知识点:TreeSet排序 理解二叉树的网站:https://www.cs.usfca.edu/~galles/visualization/Algorithms.html 需求:创建TreeSet对象,储存Student Comparable--内置比较器 */ set.add(new Student("榮",'男',22,'2107',001)); set.add(new Student("沝",'女',22,'2107',002)); set.add(new Student("桜",'女',19,'2107',003)); set.add(new Student("僡",'女',18,'2107',004)); set.add(new Student("沝心",'女',20,'2107',005)); set.add(new Student("桜樱",'女',21,'2107',006)); for(Student stu:set){ System.out.println(stu); } } }
public class Student implement Comparable<Student>{ private String name; private char set; private int age; private String classId; private String id; public Student(){} public Student(String classId,String id){ this.classId=classId; this.id=id; } public Student(String name,char sex,int age,String classId,String id){ this.name=name; this.age=age; this.sex=sex; this.classId=classId; this.id=id; } public String getName(){return name;} public void setName(String name){this.name=name;} public String getSex(){return Sex;} public void setSex(char sex){this.sex=sex;} public String getAge(){return age;} public void setAge(int age){this.age=age;} public String getClassId(){return classId;} public void setClassId(String classId){this.classId=classId;} public String getId(){return id;} public void setId(String id){this.id=id;} @Override public boolean equals(Object obj) { if(this == obj){ return true; } if(obj instanceof Student){ Student stu = (Student) obj; if(this.classId.equals(stu.classId) && this.id.equals(stu.id)){ return true; } } return false; } @Override public String toString() { return name + "\t" + sex + "\t" + age + "\t" + classId + "\t" + id; } //比较规则 //需求:按照年龄排序 @Override public int compareTo(Student o) { return this.age - o.age; } }
泛型:
含义:数据安全的做法
泛型限定:
- ?表示什么类型都可以
- ?extends A表示元素必须是A类或A的子类
- ? super A表示元素不行是A类或A的父类
迭代器
含义:遍历集合中的数据
分类:Iterator 和ListIterator区别
Iterator: Collection接口下所有的实现类都可以获取的迭代器,可以在遍历时删除元素
ListIterator:List接口下所有的实现类可以获取的迭代器,可以在遍历时
- 删除
- 替换
- 添加元素
- 指定下标开始遍历
- 还可以倒叙遍历
比较接口
作用:排序时使用
分类:
- 内置比较器:Comparable-----方法compareTo()
- 外置比较器:Comparator-----方法compare()
使用场景:
- 内置比较器:对象要想存入TreeSet、TreeMap中,对象所属的类必须要实现内置比较器
- 外置比较器:当内置比较的规则不满足现在的需求,但又不能改动内置比较规则是所使用的的内部类添加compare方法来满足需求
优先级别:外置比较器 >>>内置比较器
注意:
理解set为什么是无序:
无序:存入顺序和去除顺序不一致,无序不等于随机
使用上的区别:
LinkedList特有:
队列模式—先进先出(removeFirst())
栈模式 -----先进后出(remove Last())
效率上的区别:
- ArrayList底层数据结构是一维数组
- LinkedList底层数据结构是双向链表
- 添加情况:
- ArrayLis不进行扩容的时候效率快
- LinkedList进行扩容的时候效率快
- 删除:LinkedList效率快
- 修改:ArrayList效率快
- 查询:ArrayList效率快
- 注意:工作中常常使用ArrayList,因为很多需求都需要使用查询功能,ArrayList查询更快
各种集合的应用场景
ArrayList:存数据,线程不安全
LinkedList:队列模式,栈模式,线程不安全
Vector:现在基本上被弃用了,线程安全
Stack:现在基本上被弃用了,线程安全
HashSet:去重复+无顺序,线程不安全,注意:无顺序不代表随机
LinkedHasSet:去重复+有顺序,线程不安全
TreeSet:排序,线程不安全
:
无序:存入顺序和去除顺序不一致,无序不等于随机
使用上的区别:
LinkedList特有:
队列模式—先进先出(removeFirst())
栈模式 -----先进后出(remove Last())
效率上的区别:
- ArrayList底层数据结构是一维数组
- LinkedList底层数据结构是双向链表
- 添加情况:
- ArrayLis不进行扩容的时候效率快
- LinkedList进行扩容的时候效率快
- 删除:LinkedList效率快
- 修改:ArrayList效率快
- 查询:ArrayList效率快
- 注意:工作中常常使用ArrayList,因为很多需求都需要使用查询功能,ArrayList查询更快
各种集合的应用场景
ArrayList:存数据,线程不安全
LinkedList:队列模式,栈模式,线程不安全
Vector:现在基本上被弃用了,线程安全
Stack:现在基本上被弃用了,线程安全
HashSet:去重复+无顺序,线程不安全,注意:无顺序不代表随机
LinkedHasSet:去重复+有顺序,线程不安全
TreeSet:排序,线程不安全