1.认识集合
Java中可以使用数组存储多个类型相同的数据,但是使用数组存在如下缺陷:
数组长度固定,不能很好的适应元素动态变化的情况;
可以通过数组名.length获取数组的长度,但是不能直接获取数组中实际存储的元素个数。
针对数组的缺陷,Java提供了比数组更灵活、更实用的集合框架,可大大提高软件的开发效率,并且不同的集合可适用于不同应用场合。
1.1 Java集合框架
Java集合框架提供了一套性能优良、使用方便的接口和类,都位于java.util包中,主要关系图如下
可以看出,Java的集合接口主要有Collection接口和Map接口。其中Collection接口有两个常用子接口:List接口和Set接口。List接口常用实现类:ArrayList类和LinkedList类。Map接口常用子接口:Set接口。Set接口常用实现类:HashSet类。即:Java集合框架主要由3大类接口组成:List接口,Set接口,Map接口。
2.List接口
1.Collection接口是最基本的集合接口,存储的是一组不唯一、无序的对象;List接口继承Collection接口,是有序集合。可以使用索引(下标)访问List接口中的元素,类似数组。
2.List接口中允许存放重复的元素,即:List接口存储的是一组不唯一、有序的对象。
List接口常用的两个实现类:ArrayList类和LinkedList类。
2.1 ArrayList类
ArrayList实现了长度可变的数组,在内存中分配连续的空间,即又称ArrayList为动态数组。
ArrayList集合中可以添加任何类型的数据,并且添加的数据都会转换成Object类型
ArrayList类常用方法
方法名 | 说明 |
boolean add(Object o); | 将指定的元素添加到列表的末尾,起始索引位置从零开始 |
void add(int index,Object o); | 在指定的索引位置添加元素,添加位置必须介于0和列表中元素个数之间 |
Object get(int index); | 返回指定索引位置的元素,返回值是Object类型,使用前需要进行强制类型转换 |
boolean contains(Object o); | 判断列表中是否包含指定元素 |
boolean remove(Object o); | 删除列表中指定元素 |
int size(); | 返回列表中的元素个数 |
Object remove(int index); | 删除列表中指定位置的元素,起始索引从零开始 |
Collection接口常用通用方法还有:clear()、isEmpty()、toArray()、iterator()。
2.2 补充:Iterator接口
1.Iterator接口表示对集合进行迭代的迭代器,为集合而生,专门实现集合的遍历。
2.凡是由Collection接口派生的接口或者类都实现了iterator()方法,iterator()方法返回的是一个Iterator对象。
常用方法:hasNext()和next()。
hasNext():判断是否存在一个可访问的元素,如果仍有元素可以迭代,则返回true
next():返回要访问的下一个元素
使用Iterator遍历集合
Iterator it=new Iterator();//获取集合迭代器Iterator对象
//通过迭代器一次输出集合中所有的元素信息
while(it.hasNext(){
Object object=it.next();
}
2.3 LinkedList类
LinkedList类是List接口的链表实现类,它支持实现所有List接口可选的列表的操作,并且允许元素值是任何类型,包括null。
LinkedList类常用方法
除了包含ArrayList类所包含的方法外,还提供了以下一些方法:
void addFirst(Object o)//将指定元素插入到当前集合首部
void addLast(Object o)//将指定元素插入到当前集合尾部
Object getFirst()//获取当前集合的第一个元素
Object getLast()//获取当前集合的最后一个元素
Object removeFirst()//移除并返回当前集合的第一个元素
Object removeLast()//移除并返回当前集合的最后一个元素
ArrayListVSLinkedList
ArrayList类的底层和数组一样,在内存中分配连续的空间,所以遍历元素和随机访问元素的效率比较高;
LinkedList类的底层是采用链接列表的存储方式,删除、插入元素的效率比较高。
2.4 代码举例说明
ArrayList集合和LinkedList集合可以使用for循环、增强for循环、迭代器(Iterator接口)三种方式遍历。
public static void main(String[] args) {
//1.准备数据:创建NewsTitle对象
NewsTitle nt1=new NewsTitle(100, "俄乌战争走向", "国际社");
NewsTitle nt2=new NewsTitle(200, "国庆放假通知", "学校通知");
NewsTitle nt3=new NewsTitle(300, "金坷垃之谜", "圣地亚哥");
//创建ArrayList对象,这个类在java.util包中,需要导包
ArrayList alt=new ArrayList();
//通过add()方法向集合添加元素
alt.add(nt1);
alt.add(nt2);
alt.add(nt3);
alt.add(nt2);
//add(int index,Object obj)方法:将元素存储到集合指定位置
alt.add(2, nt1);
//对集合中元素的操作,都是通过集合对象名alt调用方法来实现
//获取集合元素个数,即集合长度:size()方法
int size=alt.size();
System.out.println("alt集合中的元素个数:"+size);
//获取集合中的指定元素:get(int index)方法,有返回值,返回值类型是父类Object类引用对象
Object obj1=alt.get(3);//返回值是什么类型的就用什么类型的变量去接收
System.out.println(obj1);
//或者向下转型转成真正的类型来输出
NewsTitle newsTitle=(NewsTitle)obj1;
System.out.println(newsTitle);
System.out.println("-----------");
//遍历集合元素有三种方式:普通for()循环,增强for()循环,迭代器
//普通for()循环
for (int i = 0; i < alt.size(); i++) {
Object obj=alt.get(i);
NewsTitle newsTitle1=(NewsTitle)obj;
System.out.println(newsTitle1);
}
//删除集合中的元素:remove(元素名/元素下标)方法
boolean boo=alt.remove(nt1);
System.out.println("删除了nt1:"+boo);
//使用增强for循环遍历删除后的集合
for(Object obj:alt){
NewsTitle ntl=(NewsTitle)obj;
System.out.println(ntl);
}
System.out.println("----使用迭代器-----");
//使用迭代器来遍历集合:iterator()
/*Iterator:迭代器,可以看成是集合容器
集合名.iterator();将集合中的元素都转移到Iterator中
通过hasNext()方法判断iterator中是否有元素,有则返回true,无则返回false;
返回true时,通过next()方法取出元素*/
Iterator it=alt.iterator();
while(it.hasNext()){
Object obj=it.next();
NewsTitle newst=(NewsTitle)obj;
System.out.println(newst);
}
//判断集合中是否包含某个元素:contains()方法
boolean result=alt.contains(nt3);
System.out.println("集合中包含nt3这个元素:"+result);
//将集合中的元素转换为数组:toArray()方法
Object[] objs=alt.toArray();
//遍历数组
for (int i = 0; i < objs.length; i++) {
System.out.println(objs[i]);
}
//清空集合:clear()方法
alt.clear();
System.out.println(alt.size());
//isEmpty()方法
boolean boo1=alt.isEmpty();
System.out.println("集合元素清空成功:"+boo1);
}
public static void main(String[] args) {
NewsTitle nt1=new NewsTitle(100, "俄乌战争走向", "国际社");
NewsTitle nt2=new NewsTitle(200, "国庆放假通知", "学校通知");
NewsTitle nt3=new NewsTitle(300, "金坷垃之谜", "圣地亚哥");
List list=new LinkedList();//使用多态的形式创建
list.add(nt1);
list.add(nt2);
list.add(nt3);
//addFirst()方法将元素添加到集合的第一个位置
//不能这样list.addFirst(nt3);直接添加,因为addFirst()方法是LinkedList类特有方法
//接口的引用无法调用实现类中特有的方法,向下转型
LinkedList link=(LinkedList)list;
link.addFirst(nt3);
//遍历集合
for (int i = 0; i < link.size(); i++) {
Object obj1=link.get(i);//get()方法获取元素
NewsTitle newsT1=(NewsTitle)obj1;//向下转型
System.out.println(newsT1);
}
//获取集合中的第一个元素:getFirst()方法
Object obj2=link.getFirst();
NewsTitle newsT2=(NewsTitle)obj2;//向下转型
System.out.println(newsT2);
//获取集合中的最后一个元素
Object obj3=link.getLast();
NewsTitle newsT3=(NewsTitle)obj3;//向下转型
System.out.println(newsT3);
//删除集合中的第一个元素,最后一个元素
System.out.println("删除的第一个元素是:"+link.removeFirst());
System.out.println("删除的最后一个元素是:"+link.removeLast());
//清空集合:clear()
link.clear();
//判断集合是否为空
System.out.println(link.isEmpty());
}
3.Set接口
Set接口是Collection接口的另一个常用子接口,Set接口存储的是一组唯一、无序的对象。
Set接口常用的实现类有HashSet类。
3.1 HashSet类
HashSet集合特点如下:
集合内的元素是无序的;
HashSet类是非线程安全的;
允许集合元素值为null。
HashSet类常用方法:
方法说明boolean add(Object o)如果Set中尚未包含指定元素0,则添加指定元素ovoid clear()从set中移除所有元素int size()返回Set中元素的数量boolean isEmpty()如果Set不包含任何元素,则返回trueboolean contains(Object o)如果Set包含指定元素o,则返回trueboolean remove(Object o)如果指定元素o在Set集合中,则将其移除
3.2 代码举例说明
由于Set接口存储的唯一、无序的对象,所以没有get(int index)方法获取集合中的元素,进而不能使用普通for循环遍历集合。HashSet集合的遍历方式有两种:增强for循环、Iterator迭代器
//Set接口:存储的是一组唯一、无序的对象集合。HashSet类是Set接口常用的实现类
public static void main(String[] args) {
// 1.准备数据
NewsTitle nt1 = new NewsTitle(100, "俄乌战争走向", "国际社");
NewsTitle nt2 = new NewsTitle(200, "国庆放假通知", "学校通知");
NewsTitle nt3 = new NewsTitle(300, "金坷垃之谜", "圣地亚哥");
//2.创建HashSet类对象
HashSet hs=new HashSet();
//3.将元素存储到hs集合中
hs.add(nt1);
hs.add(nt2);
hs.add(nt3);
hs.add(nt2);//添加重复的元素
//获取集合元素个数size()方法
int size=hs.size();
System.out.println(size);//元素个数是3,也验证了set接口存储的数据是唯一的
//获取集合中的元素,Set集合是无序的,所以没有get()方法获取元素,不能用普通for循环
//增强for循环遍历集合
for(Object obj:hs){
NewsTitle newsT=(NewsTitle)obj;
System.out.println(newsT);//输出结果是无序的
}
System.out.println("-----迭代器------");
//通过迭代器来遍历数组
Iterator it=hs.iterator();
while(it.hasNext()){
Object obj=it.next();
NewsTitle newst=(NewsTitle)obj;
System.out.println(newst);
}
}
4.Map接口
4.1 Map接口概述
1.Map接口存储的是一对键(key)——值(value)对象,即键值对,提供键(key)到值(value)的映射;
2.Map接口中的key不要求有序,不允许重复。value同样不要求有序,但允许重复。
3.Map接口的常用方法如下:
方法 | 说明 |
Object put(Object key,Object value) | 将相互关联的一个key和一个value放入该集合,如果此Map接口中已经包含了此key对应的value,则旧值会被替代 |
Object remove(Object key) | 从当前集合中移除与指定key相关的映射,并返回与该key关联的旧value,如果key没有任何关联,则返回null |
Object get(Object key) | 获得与key关联的value,如果该key不关联任何非null值,则返回null |
boolean containsKey(Object key) | 判断集合中是否包含指定key |
boolean containsValue(Object value) | 判断集合中是否包含指定value |
boolean isEmpty() | 判断集合中是否存在元素 |
void clear() | 清空集合中所有元素 |
int size() | 返回集合元素个数 |
Set keySet() | 获得所有key的集合 |
Collection value() | 获得所有value的集合 |
4.2 使用HashMap类动态存储数据
1.Map接口中存储的数据都是键——值对,最常用的实现类是HashMap类,优点是查询效率高。
2.遍历HashMap集合可以遍历键集和值集,还可以遍历键值对,有普通for循环、增强for循环和迭代器Iterator三种方式
public static void main(String[] args) {
//创建学生对象
Student stu1=new Student("张三", 21);
Student stu2=new Student("李四", 23);
Student stu3=new Student("李华", 32);
//创建HashMap对象
HashMap hm=new HashMap();//也可以用多态:Map map=new HashMap();
hm.put(1, stu1);
hm.put(2, stu2);
hm.put(3, stu3);
//遍历map集合
//法一:先获取所有的键:keySet()方法,再通过键集获取对应的值get(key)方法
Set keys=hm.keySet();
//方式一:增强for循环
for(Object obj1:keys){
int key1=(int)obj1;
Object obj2=hm.get(obj1);
Student student=(Student)obj2;
System.out.println(key1+"对应的值是:"+student);
}
System.out.println("-----------------");
//方式二:通过迭代器遍历
Iterator it=keys.iterator();//把所有的键转移到Iterator中
while(it.hasNext()){
Object obj3=it.next();
int key2=(int)obj3;
Object obj4=hm.get(key2);
Student student2=(Student)obj4;
System.out.println(key2+"对应的值是:"+student2);
}
System.out.println("--------------------");
//法二:先获取键值对:entrySet()方法,再获取键getKey()和值getValue()
Set keysValues=hm.entrySet();
for (Object object : keysValues) {
//向下转型:转成Map.Entry接口
Map.Entry me=(Map.Entry)object;
//获取键
Object obj5=me.getKey();
int key3=(int)obj5;
//获取值
Object obj6=me.getValue();
Student student3=(Student)obj6;
System.out.println(key3+"对应的值是:"+student3);
}