1.认识集合

Java中可以使用数组存储多个类型相同的数据,但是使用数组存在如下缺陷:

数组长度固定,不能很好的适应元素动态变化的情况;

可以通过数组名.length获取数组的长度,但是不能直接获取数组中实际存储的元素个数。

针对数组的缺陷,Java提供了比数组更灵活、更实用的集合框架,可大大提高软件的开发效率,并且不同的集合可适用于不同应用场合。

1.1 Java集合框架

Java集合框架提供了一套性能优良、使用方便的接口和类,都位于java.util包中,主要关系图如下

Java 集合框架思维导图 java集合类框架基本接口_数据结构

可以看出,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);
		}