目录
示例6:Set集合是无序的,所以不能使用get(下标) 获取数据
2、遍历Map集合(三种方式:增强for循环、迭代器、键值对)
00、Java集合框架简介
变量:存储数据的容器,只能存储一个数组
数组:存储数据的容器,存储多个相同类型的数据
集合:存储数据的容器,存储多个不同类型的数据
1、Java集合框架:
List接口:(不唯一、有序)
ArrayList、LinkeList
Set接口:(唯一、无序)
HashSet、TreeSet
Map接口:(键唯一、值不唯一)
HashMap、TreeMap
2、为什么使用集合框架:
如果并不知道程序运行时会需要多少对象,或者需要更复杂方式存储对象——>可以使用Java集合框架。
01、认识集合
开发应用程序时,如果想存储多个同类型的数据,可以使用数组来实现,但是数组存在如下一些明显缺陷:
(1)数组长度固定不变,不能很好地适应元素数量动态变化的情况。
(2)可通过数组名.length获取数组的长度,却无法直接获取数组中实际存储的元素个数。
(3)数组采用在内存中分配连续空间的存储方式存储,根据元素信息查找时效率比较低,需要多次比较。
从以上分析可以看出数组在处理一些问题时存在明显的缺陷,针对数组的缺陷,Java提供了比数组更灵活、更实用的集合框架,可大大提高软件的开发效率,并且不同的集合可适用不同应用场合。
Java集合框架提供了一套优良、使用方便的接口和类,它们都位于java.util 包中,其主要内容及彼此之间的关系如图所示:
从图中可以看出,Java的集合类主要由Map接口和Collection接口派生而来,其中Collection接口有两个常用的子接口,即List接口和Set接口,所以通常说Java集合框架由三大类接口构成(Map接口、List接口和Set接口)。
将上述进行部分提取:
(1)Java集合框架包含的内容:
- Collection接口存储一组不唯一、无序的对象
- List接口存储一组不唯一、有序(插入顺序)的对象
- Set接口存储一组唯一、无序的对象
- Map接口存储一组键值对象,提供Key到value的映射
02、List接口
Collection接口是最基本的集合接口,可以存储一组不唯一、无序的对象,List接口继承自Collection接口,是有序集合,用户可使用索引访问List接口中的元素,类似于数组,List接口中允许存放重复元素,也就是说List可以存储一组不唯一、有序的对象。
(1)ArrayList:实现了长度可变的数组,在内存中分配连续的空间,遍历元素和随机访问元素的效率比较高。
(2)LinkedList:采用链表存储方式,插入,删除元素时效率比较高。
1、ArrayList
针对数据的一些缺陷,Java集合框架提供了ArrayList集合类,对数组进行了封装,实现了长度可变的数组,而且和数组采用相同的存储方式,在内存中分配连续的空间,如下图所示(ArrayList存储方式示意图),所以经常称ArrayList为动态数组。
0 | 1 | 2 | 3 | 4 | 5 | |
aaaa | dddd | cccc | aaaa | eeee | dddd |
但是它不等同于数组,ArrayList集合中可以添加任何类型的数据,并且添加的数据都将转换称Object类型,而在数组中只能添加同一类型的数据。
示例1:新闻管理系统
新闻管理系统,需求如下:
(1)可以存储各类新闻标题(包括ID、名称、创建者)
(2)可以获取新闻标题的总数
(3)可以逐条打印每条新闻标题的名称
代码如下所示:NewsTitle类和测试类Test类
NewsTitle类:
package cn.bdqn.demo01;
public class NewsTitle {
private int id; //ID
private String name;//名称
private String author;//创建者
//无参的构造方法
public NewsTitle() {
super();
}
//有参的构造方法
public NewsTitle(int id, String name, String author) {
super();
this.id = id;
this.name = name;
this.author = author;
}
//getter()和setter()方法
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
//toString()方法-->快捷键:右击选择sourse-->Generate toString
@Override
public String toString() {
return "NewsTitle [id=" + id + ", name=" + name + ", author=" + author
+ "]";
}
}
测试类Test类
package cn.bdqn.demo01;
import java.util.ArrayList;
public class Test {
/*新闻管理系统,需求如下:
* (1)可以存储各类新闻标题(包括ID、名称、创建者)
* (2)可以获取新闻标题的总数
* (3)可以逐条打印每条新闻标题的名称
* */
public static void main(String[] args) {
// 创建3新闻标题类对象
NewsTitle nt1 = new NewsTitle(1001, "新闻标题1", "创建者1");
NewsTitle nt2 = new NewsTitle(1002, "新闻标题2", "创建者2");
NewsTitle nt3 = new NewsTitle(1003, "新闻标题3", "创建者3");
// 准备集合容器,调用ArrayList类的无参构造方法,创建一个默认长度为10的集合容器
ArrayList al = new ArrayList();
// 将创建的新闻标题对象存储到al集合中
al.add(nt1);
al.add(nt3);
al.add(nt2);
// 获取新闻标题的总数----》获取集合中元素的个数
int size = al.size(); //int size():返回列表中的元素个数
System.out.println("新闻标题数目为:" + size);
// 可以逐条打印每条新闻标题的名称
// Object obj1 =al.get(0);
// NewsTitle newsTile1 = (NewsTitle)obj1;
// System.out.println(newsTile1.getName());
//
// Object obj2 =al.get(1);
// NewsTitle newsTile2 = (NewsTitle)obj2;
// System.out.println(newsTile2.getName());
//
// Object obj3 =al.get(2);
// NewsTitle newsTile3 = (NewsTitle)obj3;
// System.out.println(newsTile3.getName());
System.out.println("新闻标题名称为:");
//通过循环遍历更方便
for (int i = 0; i < al.size(); i++) {
Object obj = al.get(i);
NewsTitle newsTile = (NewsTitle) obj;
System.out.println(newsTile.getName());
}
}
}
在上述示例1中,ArrayList集合中存储的新闻标题对象。在ArrayList集合中可以存储任何类型的对象。
ArrayList集合因为可以使用索引来直接获取元素,所以其优点是遍历元素和随机访问的效率比较高。但是由于ArrayList集合采用了和数组相同的存储方式,在内存中分配连续的空间,因此在添加和删除非尾部元素时会导致后面所有元素的移动,这就造成在插入、删除等操作频繁的应用场景下使用ArrayList会导致性能低下。。所以数据操作频繁时,最好使用LinkedList存储数据。
2、ArrayList常用方法(使用)
ArrayList类提供了很多方法用于操作数据,如下表:
ArrayList:常用方法(0)boolean add(Object):在列表的末尾顺序添加元素,起始索引位置从0开始
(1)int size():返回列表中的元素个数
(2)Object get(int index):返回指定索引位置处的元素。取出的元素是object类型,使用前需要进行强制类型转换
(3)void add(int index,Object o):在指定的索引位置添加元素。索引位置必须介于0和列表中元素个数之间
(4)boolean contains(Object o):判断元素中是否存在指定元素,如果集合中存在你要找的元素,返回true,否则返回false
(5)boolean remove(Object o):从列表中删除元素,删除成功返回true,删除失败返回false
(6)Object remove(int index):从列表中删除指定位置元素,起始索引位置从0开始Collection接口常用通用方法还有:
(7)clear():清空集合中的所有元素
(8)isEmpty():如果此列表中没有元素,则返回 true
(9)toArray():将集合变成数组
(10)iterator():迭代器(遍历),将集合中的元素“转移”到了迭代器这么一个容器中,接下来对迭代器容器进行遍历
注:通过API查询,接口iterator():对Collection进行迭代的迭代器中,包括了三个方法,方法如下所示如下:
以下通过代码对上述方法进行解析:
示例2:新闻管理系统(在示例1基础上进行)
(1)NewsTitle类:与示例1的NewsTitle类一样
(2)测试类Test类:
package cn.bdqn.demo00;
import java.util.ArrayList;
import java.util.Iterator;
public class Test {
/*
* 可以存储各类新闻标题(包含ID、名称、创建者)
* 可以获取新闻标题的总数
* 可以逐条打印每条新闻标题的名称
*/
public static void main(String[] args) {
//创建3个新闻标题对象
NewsTitle nt1 = new NewsTitle(1001, "标题111", "张三");
NewsTitle nt2 = new NewsTitle(1002, "标题222", "李四");
NewsTitle nt3 = new NewsTitle(1003, "标题333", "王五");
NewsTitle nt4 = new NewsTitle(1004, "标题444", "老六");
//准备集合容器,调用ArrayList类的无参构造方法,创建一个默认长度为10的集合容量
ArrayList al = new ArrayList();
//将创建的新闻标题对象存储到al集合中
al.add(nt1);
al.add(nt3);
al.add(nt2);
/*
* ArrayList:常用方法
* (1)int size():返回列表中的元素个数
* (2)Object get(int index):返回指定索引位置处的元素。取出的元素是object类型,使用前需要进行强制类型转换
* (3)void add(int index,Object o):在指定的索引位置添加元素。索引位置必须介于0和列表中元素个数之间
* (4)boolean contains(Object o):判断元素中是否存在指定元素,如果集合中存在你要找的元素,返回true,否则返回false
* (5)boolean remove(Object o):从列表中删除元素,删除成功返回true,删除失败返回false
* (6)Object remove(int index):从列表中删除指定位置元素,起始索引位置从0开始
* Collection接口常用通用方法还有:
* (7)clear():清空集合中的所有元素
* (8)isEmpty():如果此列表中没有元素,则返回 true
* (9)toArray():将集合变成数组
* (10)iterator():迭代器(遍历),将集合中的元素“转移”到了迭代器这么一个容器中,接下来对迭代器容器进行遍历
*
* */
System.out.println("----------------------(1)-------------------------");
//获取新闻的总数-->获取元素中集合的个数
//(1)int size():返回列表中的元素个数
int size = al.size();
System.out.println("集合中元素的个数:"+size);
System.out.println("----------------------(2)-1 不建议-------------------------");
// 可以逐条打印每条新闻标题的名称
// Object get(int index):返回指定索引位置处的元素。取出的元素是Object类型,使用前需要进行强制类型转换
// Object obj1 =al.get(0);
// NewsTitle newsTile1 = (NewsTitle)obj1;
// System.out.println(newsTile1.getName());
//
// Object obj2 =al.get(1);
// NewsTitle newsTile2 = (NewsTitle)obj2;
// System.out.println(newsTile2.getName());
//
// Object obj3 =al.get(2);
// NewsTitle newsTile3 = (NewsTitle)obj3;
// System.out.println(newsTile3.getName());
System.out.println("----------------------(2)-2 -------------------------");
//逐条打印每条新闻标题的名称
//(2)Object get(int index):返回指定索引位置处的元素。取出的元素是object类型,使用前需要进行强制类型转换
for(int i=0;i<al.size();i++){
Object obj=al.get(i);
NewsTitle newsTitle = (NewsTitle)obj;
System.out.println(newsTitle.getName()+"---"+newsTitle.getAuthor());
}
System.out.println("----------------------(3)-------------------------");
//(3)void add(int index,Object o):在指定的索引位置添加元素。索引位置必须介于0和列表中元素个数之间
al.add(0, nt4); //在索引为0位置处插入nt4
NewsTitle news =(NewsTitle)al.get(0);
System.out.println(news);
System.out.println("----------------------(4)-------------------------");
//(4)boolean contains(Object o):判断元素中是否存在指定元素,如果集合中存在你要找的元素,返回true,否则返回false
boolean result1=al.contains(nt3);
System.out.println("集合中存在你要找的元素nt3:"+result1);
System.out.println("----------------------(5)-------------------------");
//(5)boolean remove(Object o):从列表中删除元素,删除成功返回true,删除失败返回false
boolean result2=al.remove(nt4);
System.out.println("删除元素成功:"+result2);
//通过遍历集合检查是否将nt4删除成功
for(int i=0;i<al.size();i++){
Object obj = al.get(i);
NewsTitle newsTitle = (NewsTitle)obj;
System.out.println(newsTitle.getName()+"--"+newsTitle.getAuthor());
}
System.out.println("----------------------(6)-------------------------");
//(6)Object remove(int index):从列表中删除指定位置元素,起始索引位置从0开始
Object obj = al.remove(0);
NewsTitle newsTitle = (NewsTitle)obj;
System.out.println(newsTitle);
System.out.println("---------------------");
for(int i=0;i<al.size();i++){
Object obj1 = al.get(i);
NewsTitle newsTitle1 = (NewsTitle)obj1;
System.out.println(newsTitle1.getName()+"--"+newsTitle1.getAuthor());
}
System.out.println("----------------------(7)-------------------------");
/* //(7)clear():清空集合中的所有元素
al.clear();
System.out.println("集合中的元素个数:"+al.size());
*/
System.out.println("----------------------(8)-------------------------");
/* //(8)isEmpty():如果列表中没有元素,则返回true
System.out.println("列表中没有元素返回true:"+al.isEmpty());*/
System.out.println("----------------------(9)-------------------------");
//(9)toArray():将集合变成数组
Object[] objto=al.toArray();
for(int i=0;i<objto.length;i++){
System.out.println(objto[i]);
}
System.out.println("----------------------(10)-------------------------");
//(10)iterator():迭代器(遍历),将集合中的元素“转移”到了迭代器这么一个容器中,接下来对迭代器进行遍历
Iterator it = al.iterator();
/*遍历IT这个容器,先使用Iterator接口中hasnext()方法判断容器中是否有容器,
* 有,使用next()取出,然后在判断,如果有,就取出,继续再判断*/
//it.hasnext():判断迭代器中是否有元素,如果有返回true
while(it.hasNext()){
//取出元素
Object object=it.next();
NewsTitle nt = (NewsTitle)object;
System.out.println(nt);
}
System.out.println("-------------------------");
//增强for循环进行遍历
for (Object ob : al) {
NewsTitle nt = (NewsTitle)ob;
System.out.println(nt);
}
}
}
输出结果:
示例3:新闻管理系统(与示例2在"准备容器"处的区别)
新闻管理系统,需求如下:
可以添加头条新闻标题
获取头条和最末条新闻标题
可以删除末条新闻标题
与示例2的区别:在“准备容器处的区别”
示例1:ArrayList al = new ArrayList();
示例2:List list = new ArrayList();//父类的引用指向子类的实例
步骤:
(1)准备集合中的内容,创建3个NewsTitle类对象
(2)准备容器,创建ArrayList集合对象
(3)将对象元素存储到集合中
(4)可以添加头条新闻标题
(5)获取头条和最末条新闻标题
(6)可以删除末条新闻标题
(7)通过使用增强for循环进行遍历
代码:
(1)NewsTitle类:与示例1的NewsTitle类一样
(2)测试类Test类:
package cn.bdqn.demo02;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
/*
* 新闻管理系统,需求如下
* 可以添加头条新闻标题
* 获取头条和最末条新闻标题
* 可以删除末条新闻标题
*/
//准备集合中的内容,创建3个NewsTtitle类对象
NewsTitle nt1 = new NewsTitle(1001, "标题111", "张三");
NewsTitle nt2 = new NewsTitle(1002, "标题222", "李四");
NewsTitle nt3 = new NewsTitle(1003, "标题333", "王五");
NewsTitle nt4 = new NewsTitle(1004, "标题444", "老六");
//准备容器,创建ArrayList集合对象
List list = new ArrayList();
System.out.println("------------(1)将对象元素存储到集合中-----------");
//将对象元素存储到集合中
list.add(nt1);
list.add(nt2);
list.add(nt3);
//遍历验证
for (Object object : list) {
System.out.println(object);
}
System.out.println("------------(2)添加头条新闻标题-----------");
//可以添加头条新闻标题
list.add(0, nt4);
//遍历验证
for (Object object : list) {
System.out.println(object);
}
System.out.println("------------(3)获取头条和最末条新闻标题-----------");
//获取头条和最末条新闻标题
System.out.println(list.get(0));
System.out.println(list.get(list.size()-1));
System.out.println("------------(4)删除末条新闻标题-----------");
//可以删除末条新闻标题
list.remove(list.size()-1);
//遍历验证
for (Object object : list) {
System.out.println(object);
}
System.out.println("------------(5)遍历-----------");
for (Object object : list) {
System.out.println(object);
}
}
}
输出结果:
3、LinkedList常用方法(使用)
LinkedList常用方法
(1)void addFirst(Object):在列表的首部添加元素
(2)void addLast():在列表的末尾添加元素
(3)Object getFirst():返回列表中的第一个元素
(4)Object getLast():返回列表中的最后一个元素
(5)Object removeFirst():删除并返回列表中的第一个元素
(6)Object removeLast():删除并返回列表中的最后一个元素
示例4:新闻管理系统(同示例3进行对比)
新闻管理系统,需求如下:
可以添加头条新闻标题
获取头条和最末条新闻标题
可以删除末条新闻标题
代码:
(1)NewsTitle类:与示例1的NewsTitle类一样
(2)测试类Test类:
package cn.bdqn.demo03;
import java.util.LinkedList;
import cn.bdqn.demo00.NewsTitle;
public class Test {
public static void main(String[] args) {
/*
* 新闻管理系统,需求如下
* 可以添加头条新闻标题
* 获取头条和最末条新闻标题
* 可以删除末条新闻标题
*/
// 准备集合中的内容,创建3个NewsTitle类对象
NewsTitle nt1 = new NewsTitle(1001, "标题111", "张三");
NewsTitle nt2 = new NewsTitle(1002, "标题222", "李四");
NewsTitle nt3 = new NewsTitle(1003, "标题333", "王五");
NewsTitle nt4 = new NewsTitle(1004, "标题444", "老六");
NewsTitle nt5 = new NewsTitle(1005, "标题555", "孙七");
//准备容器,创建LinkedList对象
LinkedList list = new LinkedList();
list.add(nt1);
list.add(nt2);
list.add(nt3);
System.out.println("-----------(1)添加头条新闻标题--------");
list.addFirst(nt4); //(1)添加头条新闻标题
System.out.println("-----------(2)添加最末条新闻标题--------");
list.addLast(nt5); //(2)添加最末条新闻标题
//通过遍历检查
for (Object object : list) {
System.out.println(object);
}
System.out.println("-----------(3)(4)获取头条和最末条新闻标题--------");
System.out.println(list.getFirst()); //(3) 获取头条新闻标题
System.out.println(list.getLast()); //(4) 获取最末条新闻标题
System.out.println("-----------(5)(6)删除头条和最末条新闻标题--------");
list.removeFirst(); //(5)删除头条新闻标题
list.removeLast(); //(6)删除末条新闻标题
System.out.println("-----------删除元素后进行遍历--------");
for (Object object : list) {
System.out.println(object);
}
}
}
输出结果
03、Set接口
(1)Set接口存储唯一、无序的对象
(2)HashSet是Set接口常用的实现类
(3)Set中存放对象的引用
1、HashSet
假如现在需要在很多数据中查找某个数据,LinkedList类就无需考虑了 ,它的数据结构决定了它的查找效率低下。如果使用ArrayList类,在不知道数据的索引且需要全部遍历的情况下,效率一样很低下。为此Java集合框架提供了一个查找效率高的集合类HashSet。HashSet类实现了Set接口,是使用Set集合时最常用的一个实现类。
HashSet集合的特点如下:
(1)集合内的元素是无序排列的。
(2)HashSet类是非线程安全的
(3)允许集合元素值为null
示例5: Set的唯一性
(1)Demo类
package cn.bdqn.demo04;
import java.util.HashSet;
import java.util.Set;
public class Demo {
public static void main(String[] args) {
Set set = new HashSet();
String s1 = new String("java");
String s2 = s1;
String s3 = new String("JAVA");
set.add(s1);
set.add(s2);
set.add(s3);
System.out.println(set.size());//2
}
}
(2)输出结果为:2
示例6:Set集合是无序的,所以不能使用get(下标) 获取数据
代码:
(1)NewsTitle类:与示例1的NewsTitle类一样
(2)测试类Test类:
package cn.bdqn.demo04;
import java.util.HashSet;
import java.util.Iterator;
public class Test {
public static void main(String[] args) {
//准备数据:创建NewsTitle对象
NewsTitle nt1 = new NewsTitle(1001, "Java中还有这么神奇的事情", "张三");
NewsTitle nt2 = new NewsTitle(1002, "合肥将变成一个没有传销的城市", "李四");
NewsTitle nt3 = new NewsTitle(1003, "合肥比亚迪即将建成开厂", "王五");
NewsTitle nt4 = new NewsTitle(1004, "大湖名城,创新高低", "赵六");
NewsTitle nt5 = new NewsTitle(1005, "大湖名城,创新高低", "孙七");
//准备容器
HashSet hs = new HashSet();
hs.add(nt1);
hs.add(nt2);
hs.add(nt3);
hs.add(nt4);
hs.add(nt5);
hs.add(nt1);
hs.add(nt1);
System.out.println(hs.size());//5
//遍历
for (Object object : hs) {
System.out.println(object);
}
System.out.println("-------------------");
//set集合是无序的,所以不能使用get(下标)获取元素
//hs.get(0); --->错误
Iterator it = hs.iterator();
while(it.hasNext()){
Object obj =it.next();
NewsTitle nt = (NewsTitle)obj;
System.out.println(nt);
}
}
}
输出结果:
2、HashSet类的常用方法(使用)-->待添加代码
HashSet常用方法:
(1)boolean add(Object):如果Set中尚未包含指定元素o,则添加指定元素o
(2)void clear():从Set中移除所有元素
(3)int size():返回Set中的元素的数量(Set的容量)
(4)boolean isEmpty():如果Set不包含任何元素,则返回true
(5)boolean contains(Object o):如果Set包含指定元素o,则返回true
(6)boolean remove(Object o):如果指定元素o存在于Set中,则将其移除
03、Iterator接口
1、Iterator接口概述
Iterator接口表示对集合进行迭代的迭代器。Iterator接口为集合而生,专门实现集合的遍历。此接口主要有如下两个方法:
(1)HasNext():判断是否存在下一个可访问的元素,如果仍有元素可以迭代,则返回true。
(2)next():返回要访问的下一个元素
凡是由Collection接口派生而来的接口或类,都实现iterate()方法,iterate()方法返回一个Iterator对象。
2、使用Iterator遍历集合
下面通过示例7来学习使用迭代器Iterator遍历ArrayList集合。
示例7:迭代器Iterator遍历ArrayList集合
package a1;
import java.util.ArrayList;
import java.util.Iterator;
public class Demo01 {
/*
* 步骤: (1)导入Iterator接口 (2)使用集合的iterate()方法返回Iterator对象 (3)while循环遍历
* (4)使用Iterator的hasNext()方法判断是否存在下一个可访问的元素
* (5)使用Iterator的next()方法返回要访问的下一个元素
*/
public static void main(String[] args) {
// 准备集合容器
ArrayList list = new ArrayList();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("老六");
System.out.println("使用Iterator遍历,分别是:");
// iterator():迭代器(遍历),将集合中的元素“转移”到了迭代器这么一个容器中,接下来对迭代器进行遍历
Iterator it = list.iterator();
/*
* 遍历IT这个容器,先使用Iterator接口中hasnext()方法判断容器中是否有容器,
* 有,使用next()取出,然后在判断,如果有,就取出,继续再判断
*/
// it.hasnext():判断迭代器中是否有元素,如果有返回true
while (it.hasNext()) {
String name = (String) it.next();
System.out.println(name);
}
}
}
输出结果:
04、Map接口
Map接口存储一组成对的键(key)--值(value)对象,提供key到value的映射,通过key来检索。Map接口中的key不要求有序,不允许重复。value同样不要去有序,但允许重复。
1、Map接口的常用方法
(1)Object put(Object key,Object value):将相互关联的一个key与一个value放入该集合,如果此Map接口中已经包含了Key对应的value,则旧值将被替换
(2)int size():返回集合中元素的数量
(3)Object get(Object key):获得与Key相关的value。如果该key不关联任何非null值,则返回null
(4)Object remove(key):根据键来删除键值对,返回值是键对应的值
(5)boolean containsKey(Object key):判断集合中是否存在key,存在返回true,不存在返回false
(6)boolean containsValue(Object value):判断集合中是否存在value,存在返回true,不存在返回false
(7)Set keySet():获取所有的Key集合--->(使用增强for循环、使用迭代器Iterator())
(8)Collection values():获取所有value的集合--->(使用增强for循环、使用迭代器Iterator())
(9)boolean isEmpty():判断集合中是否存在元素,如果列表中没有元素,则返回true,否则返回false
2、遍历Map集合(三种方式:增强for循环、迭代器、键值对)
遍历Map集合
(10)-1 使用增强型for循环
(10)-2 通过迭代器Iterator()实现遍
(10)-3 键值对:使用键值对的方式取出集合中的键值对
3.通过示例对Map接口的常用方法、遍历集合进行解析
示例8:对Map接口的常用方法、遍历集合进行解析
package cn.bdqn.demo05;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class Test {
public static void main(String[] args) {
//(1)Object put(Object key,Object value):将相互关联的一个key与一个value放入该集合,如果此Map接口中已经包含了Key对应的value,则旧值将被替换
//(2)int size():返回集合中元素的数量
//(3)Object get(Object key):获得与Key相关的value。如果该key不关联任何非null值,则返回null
//(4)Object remove(key):根据键来删除键值对,返回值是键对应的值
//(5)boolean containsKey(Object key):判断集合中是否存在key,存在返回true,不存在返回false
//(6)boolean containsValue(Object value):判断集合中是否存在value,存在返回true,不存在返回false
//(7)Set keySet():获取所有的Key集合--->(使用增强for循环、使用迭代器Iterator())
//(8)Collection values():获取所有value的集合--->(使用增强for循环、使用迭代器Iterator())
//(9)boolean isEmpty():判断集合中是否存在元素,如果列表中没有元素,则返回true,否则返回false
//(10)遍历Map集合()
//(10)-1 使用增强型for循环
//(10)-2 通过迭代器Iterator()实现遍
//(10)-3 键值对:使用键值对的方式取出集合中的键值对
//准备键值对容器用来存储键值对
HashMap hm = new HashMap();
System.out.println("---------------(1)---------------");
//向集合中存储数据
//(1)Object put(Object key,Object value):将相互关联的一个key与一个value放入该集合,如果此Map接口中已经包含了Key对应的value,则旧值将被替换
hm.put("CN", "中华人民共和国");
hm.put("RU", "俄罗斯联邦");
hm.put("US", "美利坚合众国");
hm.put("JP", "日本");
System.out.println("---------------(2)---------------");
//(2)int size():返回集合中元素的数量
System.out.println(hm.size()); //4
System.out.println("---------------(3)---------------");
//(3)Object get(Object key):获得与Key相关的value。如果该key不关联任何非null值,则返回null
Object obj1 = hm.get("CN");
String str1 = (String)obj1;
System.out.println(str1); //中华人民共和国
//System.out.println(hm.get("CN")); //???
System.out.println("---------------(4)---------------");
//(4)Object remove(key):根据键来删除键值对,返回值是键对应的值
Object obj2 = hm.remove("JP");
String str2 = (String)obj2;
System.out.println(str2); //日本
System.out.println("---------------(5)---------------");
//(5)boolean containsKey(Object key):判断集合中是否存在key,存在返回true,不存在返回false
System.out.println(hm.containsKey("CN"));//true
System.out.println(hm.containsKey("JP"));//false
System.out.println("---------------(6)---------------");
//(6)boolean containsValue(Object value):判断集合中是否存在value,存在返回true,不存在返回false
System.out.println(hm.containsValue("中华人民共和国"));//true
System.out.println(hm.containsValue("日本"));//false
System.out.println("---------------(7)---------------");
//(7)Set keySet():获取所有的Key集合
//System.out.println(hm.keySet()); //此情况输出的为:[US, RU, CN]
System.out.println("---------------(7)-1 使用增强for循环---------------");
// 1) 使用增强for循环
Set keys1 = hm.keySet();
for (Object object : keys1) {
String key = (String)object;
System.out.println(key);
/*US
RU
CN
*/
}
System.out.println("---------------(7)-2 使用迭代器Iterator()---------------");
// 2)使用迭代器Iterator()
Set keys2 = hm.keySet();
Iterator it = keys2.iterator();
while(it.hasNext()){
Object obj = it.next();
String key=(String)obj;
System.out.println(key);
}
System.out.println("---------------(8)---------------");
//(8)Collection values():获取所有value的集合
//System.out.println(hm.values()); //此情况输出的为:[美利坚合众国, 俄罗斯联邦, 中华人民共和国]
System.out.println("---------------(8)-1 使用增强for循环---------------");
Collection coll1 = hm.values();
for (Object object : coll1) {
String value = (String)object;
System.out.println(value);
}
System.out.println("---------------(8)-2 使用迭代器Iterator()---------------");
// 2)使用迭代器Iterator()
Collection coll2 = hm.values();
Iterator it1 = coll2.iterator();
while(it1.hasNext()){
Object obj = it1.next();
String values = (String)obj;
System.out.println(values);
}
System.out.println("---------------(9)---------------");
//(9)boolean isEmpty():判断集合中是否存在元素,如果列表中没有元素,则返回true,否则返回false
System.out.println("如果列表中没有元素,则返回true:"+hm.isEmpty()); //false
//(10)上述(7)(8)结合,遍历Map集合
System.out.println("---------------(10)-1 使用增强型for循环---------------");
//通过增强for循环
Set key11 = hm.keySet(); //获取所有key的集合,Object是所有类的父类,Set类是其子类,故获取到的key是Object,需要进行强转为String
for (Object object : key11) {
String key = (String)object; //因为获取到的键是Object,需强转为String,此时key为String
Object obj = hm.get(key); //通过Object get(key)获得与Key相关的value,也是Object,需要进行强转为String
String value = (String)obj; //将value强转为String
System.out.println(key+"--"+value);
}
System.out.println("---------------(10)-2 通过迭代器Iterator()实现遍历---------------");
Set key22 = hm.keySet(); //获取所有key的集合,Object是所有类的父类,Set类是其子类,故获取到的key是Object,需要进行强转为String
//iterator():迭代器(遍历),将集合中的元素“转移”到了迭代器这么一个容器中,接下来对迭代器进行遍历
Iterator it2 = key22.iterator();
/*遍历it2这个容器,先使用Iterator接口中hasnext()方法判断容器中是否有容器,
* 有,使用next()取出,然后在判断,如果有,就取出,继续再判断*/
//it2.hasnext():判断迭代器中是否有元素,如果有返回true
while(it2.hasNext()){
Object obj = it2.next(); //next()返回迭代的下一个元素,每个元素迭代都是Object类的,需要进行强转为String
String key = (String)obj; //强转为String
Object obj3 = hm.get(key); //通过Object get(key)获得与Key相关的value,也是Object,需要进行强转为String
String value = (String)obj3; //强转为String
System.out.println(key+"--"+value);
}
System.out.println("---------------(10)-3 键值对:使用键值对的方式取出集合中的键值对---------------");
Set keyValue = hm.entrySet();//将集合中的键值对全部取出来存储到Set集合
//System.out.println(keyValue); //输出结果为:[US=美利坚合众国, RU=俄罗斯联邦, CN=中华人民共和国]
Iterator iterator = keyValue.iterator();//将Set集合中的元素存储到迭代器中
while(iterator.hasNext()){
Object obj = iterator.next();//使用next()方法获取迭代器中的元素
Map.Entry me = (Map.Entry)obj;//键值对元素的类型为Map.Entry
Object obj11=me.getKey();//键值对类型对象调用getKey()方法可以获取键值对的键
String key = (String)obj11;
Object obj22 = me.getValue();//键值对类型对象调用getValue()方法可以获取键值对的值
String value = (String)obj22;
System.out.println(key+"--"+value);
}
}
}
输出结果:
练习01:根据学员英文名找到学员对象
需求说明:
学员应聘至外企工作,每个学员都会有一个英文名称,对应该学员对象。请实现通过英文名称,获得该学员对象的详细信息
学员属性包括姓名以及性别。
(1)Student类:
(2)测试类Test类:
package cn.bdqn.demo06;
public class Student {
private String name;
private String gender;
public Student() {
super();
}
public Student(String name, String gender) {
super();
this.name = name;
this.gender = gender;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Student [name=" + name + ", gender=" + gender + "]";
};
}
package cn.bdqn.demo06;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Test {
/*
* 需求说明
* 学员应聘至外企工作,每个学员都会有一个英文名称,对应该学员对象。
* 请实现通过英文名称,获得该学员对象的详细信息
* 学员属性包括姓名以及性别
*/
public static void main(String[] args) {
//创建学生对象
Student stu1 = new Student("张三", "男");
Student stu2 = new Student("李四", "男");
Student stu3 = new Student("如花", "女");
//创建HashMap集合对象
HashMap hm = new HashMap();
//将学生对象添加到集合中
hm.put("jack", stu1);
hm.put("tom", stu2);
hm.put("rose", stu3);
Object obj = hm.get("jack");
Student stu = (Student)obj;
System.out.println("Jack对应的学员信息为:姓名:"+stu.getName()+",性别:"+stu.getGender());
System.out.println("--------------------------");
//使用键值对的方式遍历输出所有学员的姓名和性别
Set set =hm.entrySet();
for(Object object:set){
Map.Entry me = (Map.Entry)object;
//获取键值对的键
Object obj1 = me.getKey();
String key = (String)obj1;
//获取键值对的值
Object obj2=me.getValue();
Student student = (Student)obj2;
System.out.println(key+"对应的学员姓名:"+student.getName()+",性别为:"+student.getGender());
}
}
}
05、Collections算法类
Collections类是Java提供的一个集合操作工具类,它包含了大量的静态方法,用于实现对集合元素的排序、查找和替换等操作。
注意:Collections和Collection是不同的,前者是集合的操作类,后者是集合接口。
1、对集合元素进行排序与查找
排序是针对集合的一个常见需求。要排序就要知道两个元素哪个大哪个小。在Java中,如果想实现一个类的对象之间比较大小,那么这个类就要实现Comparable接口,此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的compareTo()方法被称为它的自然比较方法。此方法用于比较此对象与指定对象的顺序,如果该对象小于、等于或大于指定对象,则分别返回整数、零或正整数。
compareTo()方法的定义语法格式:int compareTo(Object obj);
其中:
(1)参数:obj即要比较的对象
(2)返回值:负整数、零或正整数,根据此对象是小于、等于还是大于指定对象返回不同的值。
实现此接口的对象列表(和数组)可以通过Collections.sort()方法(和Arrays.sort()方法)进行自动排序。
2、排序、查找、查找最大值/最小值
示例9:排序、查找、查找最大值/最小值
(1)Collections.sort():对集合进行排序:排序
(2)int binarySearch(集合名,查找的数据):查找元素,返回查找元素所在的下标,如果查找不到元素,返回一个负值。 注意:使用该方法之前,对先对集合进行升序排序,否则不能保证查询结果的正确性。
(3)max()/min():求集合中的最大值最小值
(4)Collections.reverse(集合名):反转指定列表中元素的顺序。
package 排序_查找_最大值.最小值;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
public class Demo01 {
public static void main(String[] args) {
//创建一个ArrayList集合对象,里面存储String类型的数据
ArrayList<String> al = new ArrayList<String>();
al.add("wseurfhu");
al.add("dsfsdf");
al.add("asdewre");
al.add("sdfsf");
al.add("afhth");
System.out.println("集合排序之前:");
for (String string : al) {
System.out.println(string);
}
System.out.println("----------------(1) 排序-----------------");
//(1)Collections.sort():对集合进行排序
Collections.sort(al);
System.out.println("集合排序之前:");
for (String string : al) {
System.out.println(string);
}
System.out.println("----------------(2) 查找-----------------");
/*(2)int binarySearch(集合名,查找的数据):查找元素,
* 返回查找元素所在的下标,如果查找不到,返回一个负值。
* 注意:使用该方法之前,先对集合进行升序排列,否则不能保证查询结果的正确性
*/
int index = Collections.binarySearch(al, "sdfsf");
System.out.println(index);
System.out.println("----------------(3) 最大值/最小值-----------------");
//(3)max()/min():求集合中的最大值最小值
String max = Collections.max(al);
System.out.println(max);
String min = Collections.min(al);
System.out.println(min);
System.out.println("----------------(4)反转列表中元素的顺序 -----------------");
//Collections.reverse(集合名):反转指定列表中元素的顺序。
Collections.reverse(al);
//使用迭代器Iterator()实现遍历
System.out.println("集合元素反转之后:");
Iterator<String> it = al.iterator();
while(it.hasNext()){
String str = it.next();
System.out.println(str);
}
}
}
3、Collections排序
(1)Collections类可以对集合进行排序、查找和替换操作
(2)实现一个类的对象之间比较大小,该类要实现Comparable接口--->(重写CompareTo方法)
(3)Comparable接口中的CompareTo方法:比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。
示例10:Collections排序(通过)
(1)学生类Student实现了Comparable接口,重写了compareTo()方法,通过比较学号实现对象之间的大小比较。
(2)使用Collections类的静态方法sort()和binarySearch()对LIst集合进行排序和查找。
实现步骤一:(Student类)
(1)创建Student类
(2)添加属性姓名、学号
(3)实现Comparable接口、comparaTo()方法
实现步骤二:(StudentTest类)
(1)导入相关类
(2)初始化数据
(3)遍历排序前集合并输出
(4)使用Collections类的sort()方法排序
(5)遍历排序后集合并输出
(6)查找排序后某元素的索引
代码:
(1)Student类
(2)测试类StudentTest
package cn.bdqn.demo08;
public class Student implements Comparable<Student> {
private String name; //姓名
private int stuId; //学号
public Student() {
super();
}
public Student(String name, int stuId) {
super();
this.name = name;
this.stuId = stuId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getStuId() {
return stuId;
}
public void setStuId(int stuId) {
this.stuId = stuId;
}
@Override
public String toString() {
return "Student [name=" + name + ", stuId=" + stuId + "]";
}
@Override
//重写compareTo()方法
public int compareTo(Student student) {
//比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。
if(this.stuId<student.stuId){
return -1;
}else if(this.stuId==student.stuId){
return 0;
}else{
return 1;
}
}
}
元素之间可以比较大小之后,就可以使用Collections类的sort()方法对元素排序操作了。前面介绍过LIst接口和Map接口,Map接口本身是无序的,所以不能对Map接口做排序操作,但是LIst接口是有序的,所以可以对List接口进行排序。注意:List接口中存放的元素,必须是实现了Comparable接口的元素才可以。
package cn.bdqn.demo08;
import java.util.ArrayList;
import java.util.Collections;
public class StudentTest {
public static void main(String[] args) {
//创建4个Student类对象
Student stu1 = new Student("张三", 1001);
Student stu2 = new Student("李四", 1002);
Student stu3 = new Student("王五", 1003);
Student stu4 = new Student("赵六", 1004);
//创建ArrayList集合对象
ArrayList<Student> al = new ArrayList<Student>();
al.add(stu3);
al.add(stu2);
al.add(stu4);
al.add(stu1);
System.out.println("集合排序前:");
for (Student student : al) {
System.out.println(student);
}
//自定义类存储在集合中,要想使用sort()方法进行排序,那么该自定义类要实现Comparable接口,重写Comparable接口中的compareTo()方法,定义排序规则
Collections.sort(al);
System.out.println("集合排序后:");
for (Student student : al) {
System.out.println(student);
}
}
}
06、泛型(待补充)
07、总结
(1)Collection 、List 、Set 、Map接口的联系和区别
(2)ArrayList和LinkedList的异同之处及各自的应用场合
(3)遍历集合的方法
(4)泛型集合用法及好处