一、集合的体系
二、Collection集合
2.1 集合的概述
什么是集合?
-
集合:集合是java中提供的一种容器,可以用来存储多个数据。
集合和数组有什么区别呢?
- 数组的长度是固定的 。而集合的长度是可变的。
- 数组中存储是同一类元素类型,可以存储基本数据类型。集合存储的都啊是对象,而且对象的类型可以不一致。
2.2 集合的框架
JavaSE提供了满足各种需求的API,使用API之前要了解继承和接口的架构,才能了解采用那个类,以及类与类之间如何合作,而达到灵活引用。
集合按照其存储结构可以分为两大类,分别是单列集合 java.util.Collection 和双列集合 java.util.Map 。
- Collection集合:单列集合类的根接口,用于存储一系列符合某种规则的元素,它有两个重要的子接口,分别是 java.util.List 和 java.util.Set 。其中, List 的特点是元素有序、元素可重复。 Set 的特点是元素无序,而且不可重复。 List 接口的主要实现类有 java.util.ArrayList 和 java.util.LinkedList , Set 接口的主要实现类有 java.util.HashSet 和 java.util.TreeSet 。
从上面的描述可以看出JDK中提供了丰富的集合类库,为了便于初学者进行系统地学习,接下来通过一张图来描述 整个集合类的继承体系。
橙色框里为接口类型,而蓝色框里都是实现类。
集合本身是一个工具,它存放在java.util包中。在Collection接口定义着单列集合框架中的共性内容。
2.3 Collection集合的功能介绍
Collection是所有单列集合的父类接口,因此Collection接口定义着单列集合(List和Set集合)通用的方法,这些方法可用于操作的单列集合。方法如下:
- public boolean add(E e):把给定的对象添加到当前集合中
- public void clear():清空集合中所有元素
- public boolean remove(E e):把给定的对象在当前集合中删除
- public boolean contains(E e) : 判断当前集合中是否包含给定的对象。
- public boolean isEmpty() : 判断当前集合是否为空。
- public int size() : 返回集合中元素的个数。
- public Object[] toArray() : 把集合中的元素,存储到数组中。
方法演示:
package domain;
import java.util.ArrayList;
import java.util.Collection;
/**
* @ClassName: Demo.class
* @Description:
* @Author: 喆
* @Date: 2022/6/8 17:03
* @Software: IntelliJ IDEA
**/
public class Demo {
public static void main(String[] args) {
// 创建集合对象
// 使用多态形式
Collection<String> coll = new ArrayList<String>();
// 使用方法
// 添加功能 boolean add(String s)
coll.add("小李广");
coll.add("扫地僧");
coll.add("石破天");
System.out.println(coll);
// boolean contains(E e) 判断o是否在集合中存在
System.out.println("判断 扫地僧 是否在集合中" + coll.contains("扫地僧"));
//boolean remove(E e) 删除在集合中的o元素
System.out.println("删除石破天:" + coll.remove("石破天"));
System.out.println("操作之后集合中元素:" + coll);
// size() 集合中有几个元素
System.out.println("集合中有" + coll.size() + "个元素");
// Object[] toArray()转换成一个Object数组
Object[] objects = coll.toArray();
// 遍历数组
for (int i = 0; i < objects.length; i++) {
System.out.println(objects[i]);
}
// void clear() 清空集合
coll.clear();
System.out.println("集合中内容为:" + coll);
// boolean isEmpty() 判断是否为空
System.out.println(coll.isEmpty());
}
}
tips: 有关Collection中的方法可不止上面这些,其他方法可以自行查看API学习。
三、Iterator迭代器
3.1 Iterator接口
在程序的开发中,经常要遍历集合中的元素,针对这一方面,JDK专门提供了一个接口java.util.Iterator。Iterator接口也是Java集合中的一员,但与Collection、Map接口有所不同,Collection接口与Map接口主要用于存储元素,而Iterator主要用于迭代访问(即遍历)Collection中的元素,因此Iterator对象也被称为迭代器。
想要遍历Collection集合,就要获取该集合迭代器完成迭代操作,下面介绍一下获取迭代器的方法:
- public Iterator iterator() : 获取集合对应的迭代器,用来遍历集合中的元素的。
迭代的概念:
- 迭代:即Collection集合元素的通用获取方式。在取元素之前先要判断集合中有没有元素,如果有,就把这个 元素取出来,继续在判断,如果还有就再取出出来。一直把集合中的所有元素全部取出。这种取出方式专业 术语称为迭代。
Iterator接口的常用方法如下:
- public E next() :返回迭代的下一个元素。
- public boolean hasNext() :如果仍有元素可以迭代,则返回 true。
通过案例学习使用Iterator迭代集合中元素:
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* @ClassName: IteratorDemo.class
* @Description:
* @Author: 喆
* @Date: 2022/6/8 17:03
* @Software: IntelliJ IDEA
**/
public class IteratorDemo {
public static void main(String[] args) {
// 使用多态方式 创建对象
Collection<String> coll = new ArrayList<String>();
// 添加元素到集合
coll.add("串串星人");
coll.add("吐槽星人");
coll.add("汪星人");
//遍历
//使用迭代器 遍历 每个集合对象都有自己的迭代器
Iterator<String> it = coll.iterator();
// 泛型指的是 迭代出 元素的数据类型
while(it.hasNext()){ //判断是否有迭代元素
String s = it.next();//获取迭代出的元素
System.out.println(s);
}
}
}
tips::在进行集合元素取出时,如果集合中已经没有元素了,还继续使用迭代器的next方法,将会发生 java.util.NoSuchElementException没有集合元素的错误
3.2 迭代器的实现原理
我们在之前案例已经完成了Iterator遍历集合的整个过程。当遍历集合时,首先通过调用t集合的iterator()方法获得 迭代器对象,然后使用hashNext()方法判断集合中是否存在下一个元素,如果存在,则调用next()方法将元素取 出,否则说明已到达了集合末尾,停止遍历元素。
Iterator迭代器对象在遍历集合时,内部采用指针的方式来跟踪集合中的元素,为了让初学者能更好地理解迭代器 的工作原理,接下来通过一个图例来演示Iterator对象迭代元素的过程:
在调用Iterator的next方法之前,迭代器的索引位于第一个元素之前,不指向任何元素,当第一次调用迭代器的 next方法后,迭代器的索引会向后移动一位,指向第一个元素并将该元素返回,当再次调用next方法时,迭代器的 索引会指向第二个元素并将该元素返回,依此类推,直到hasNext方法返回false,表示到达了集合的末尾,终止对 元素的遍历。
3.3 增强for循环
增强for循环(也称for each循环)是JDK1.5以后出来的一个高级for循环,专门用来遍历数组和集合的。它的内部原 理其实是个Iterator迭代器,所以在遍历的过程中,不能对集合中的元素进行增删操作。
格式:
for(元素的数据类型 变量 : Collection集合or数组){
//写操作代码
}
它用于遍历Collection和数组。通常只进行遍历元素,不要在遍历的过程中对集合元素进行增删操作。
遍历集合
package domain;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* @ClassName: Demo1.class
* @Description:
* @Author: 喆
* @Date: 2022/6/8 17:03
* @Software: IntelliJ IDEA
**/
public class Demo1 {
public static void main(String[] args) {
String[] array = {"one","two","three","four","five"};
for(int i=0;i<array.length;i++){
String str = array[i];
System.out.println(str);
}
for(String str : array){
System.out.println(str);
}
Collection c = new ArrayList();
c.add("one");
c.add("two");
c.add("three");
c.add("four");
c.add("five");
//迭代器遍历
Iterator it = c.iterator();
while(it.hasNext()){
String str = (String)it.next();
System.out.println(str);
}
//新循环遍历
for(Object o : c){
String str = (String)o;
System.out.println(str);
}
}
}
遍历数组
package domain;
/**
* @ClassName: Demo3.class
* @Description:
* @Author: 喆
* @Date: 2022/6/8 17:03
* @Software: IntelliJ IDEA
**/
public class Demo3 {
public static void main(String[] args) {
int[] arr = {3,5,6,87};
//使用增强for遍历数组
for(int a : arr){//a代表数组中的每个元素
System.out.println(a);
}
}
}
tips: 新for循环必须有被遍历的目标。目标只能是Collection或者是数组。新式for仅仅作为遍历操作出现。
四、泛型
4.1 泛型的概述
集合中是可以存放任意对象的,只要把对象存储集合后,那么这时他们都会被提升 成Object类型。当我们在取出每一个对象,并且进行相应的操作,这时必须采用类型转换。
观察下面代码:
package domain;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* @ClassName: Demo.class
* @Description:
* @Author: 喆
* @Date: 2022/6/8 17:03
* @Software: IntelliJ IDEA
**/
public class GenericDemo {
public static void main(String[] args) {
Collection coll = new ArrayList();
coll.add("abc");
coll.add("itcast");
coll.add(5);//由于集合没有做任何限定,任何类型都可以给其中存放
Iterator it = coll.iterator();
while(it.hasNext()){
//需要打印每个字符串的长度,就要把迭代出来的对象转成String类型
String str = (String) it.next();
System.out.println(str.length());
}
}
}
运行时发生了问题java.lang.ClassCastException。 为什么会发生类型转换异常呢? 我们来分析下:由于 集合中什么类型的元素都可以存储。导致取出时强转引发运行时 ClassCastException。 怎么来解决这个问题呢? Collection虽然可以存储各种对象,但实际上通常Collection只存储同一类型对象。例如都是存储字符串对象。因此 在JDK5之后,新增了泛型(Generic)语法,让你在设计API时可以指定类或方法支持泛型,这样我们使用API的时候 也变得更为简洁,并得到了编译时期的语法检查。
- 泛型:可以在类或方法中预支地使用未知的类型。
tips:一般在创建对象时,将未知的类型确定具体的类型。当没有指定泛型时,默认类型为Object类型。
4.2 使用泛型的好处
么泛型带来了哪些好处呢?
- 将运行时期的ClassCastException,转移到了编译时期变成了编译失败。
- 避免了类型强转的麻烦。
通过代码体验一下:
package domain;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* @ClassName: GenericDemo2.class
* @Description:
* @Author: 喆
* @Date: 2022/6/8 17:03
* @Software: IntelliJ IDEA
**/
public class GenericDemo2 {
public static void main(String[] args) {
Collection<String> list = new ArrayList<String>();
list.add("abc");
list.add("itcast");
// list.add(5);//当集合明确类型后,存放类型不一致就会编译报错
// 集合已经明确具体存放的元素类型,那么在使用迭代器的时候,迭代器也同样会知道具体遍历元素类型
Iterator<String> it = list.iterator();
while(it.hasNext()){
String str = it.next();
//当使用Iterator<String>控制元素类型后,就不需要强转了。获取到的元素直接就是String类型
System.out.println(str.length());
}
}
}
tips:泛型是数据类型的一部分,我们将类名与泛型合并一起看做数据类型。
4.3 泛型的定义与使用
我们在集合中会大量使用到泛型,这里来完整地学习泛型知识。 泛型,用来灵活地将数据类型应用到不同的类、方法、接口当中。将数据类型作为参数进行传递。
- 泛型在集合中被广泛使用,用来指定集合中的元素类型
- 有泛型支持的类在使用时若不指定泛型的具体类型则默认为原型Object
package domain;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* @ClassName: Demo.class
* @Description:
* @Author: 喆
* @Date: 2022/6/8 17:03
* @Software: IntelliJ IDEA
**/
public class NewForDemo {
/**
* JDK5推出时,推出了一个新的特性:增强型for循环
* 也称为新循环,它可以用相同的语法遍历集合或数组。
*
* 新循环是java编译器认可的,并非虚拟机。
*/
public static void main(String[] args) {
String[] array = {"one","two","three","four","five"};
for(int i=0;i<array.length;i++){
String str = array[i];
System.out.println(str);
}
for(String str : array){
System.out.println(str);
}
/*
* 泛型 JDK5之后推出的另一个特性。
* 泛型也称为参数化类型,允许我们在使用一个类时指定它里面属性的类型,
* 方法参数或返回值的类型,使得我们使用一个类时可以更灵活。
* 泛型被广泛应用于集合中,用来指定集合中的元素类型。
* 支持泛型的类在使用时如果未指定泛型,那么默认就是原型Object
*
* Collection接口的定义
* public interface Collection<E> ... {
*
* Collection<E> 这里的<E>就是泛型
*
* Collection中add方法的定义,参数为E
* boolean add(E e)
*/
Collection<String> c = new ArrayList<>();
c.add("one");//编译器会检查add方法的实参是否为String类型
c.add("two");
c.add("three");
c.add("four");
c.add("five");
// c.add(123);//编译不通过
//迭代器遍历
//迭代器也支持泛型,指定的与其遍历的集合指定的泛型一致即可
Iterator<String> it = c.iterator();
while(it.hasNext()){
//编译器编译代码时会根据迭代器指定的泛型补充造型代码
String str = it.next();//获取元素时无需在造型
System.out.println(str);
}
//新循环遍历
for(String str : c){
System.out.println(str);
}
}
}
五、List集合
5.1 List集合的概述和特点
- List集合的概述
- 有序集合,这里的有序指的是存取顺序
- 用户可以精确控制列表中每个元素的插入位置,用户可以通过整数索引访问元素,并搜索列表中的元
- 与Set集合不同,列表通常允许重复的元素
- List集合的特点
- 存取有序
- 可以重复
- 有索引
5.2 List集合的特有方法
- void add(int index,E element):在此集合中的指定位置插入指定的元素
- E remove(int index): 删除指定索引处的元素,返回被删除的元素
- E set(int index,E element): 修改指定索引处的元素,返回被修改的元素
- E get(int index) :返回指定索引处的元素
代码如下:
package collection;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* @ClassName: Demo01List.class
* @Description:
* @Author: 喆
* @Date: 2022/6/8 19:39
* @Software: IntelliJ IDEA
**/
public class Demo01List {
/*
void add(int index,E element):在此集合中的指定位置插入指定的元素
E remove(int index): 删除指定索引处的元素,返回被删除的元素
E set(int index,E element): 修改指定索引处的元素,返回被修改的元素
E get(int index) :返回指定索引处的元素
*/
public static void main(String[] args) {
// 创建一个List集合
List<String> list = new ArrayList<>();
// 往集合中添加元素
list.add("a");
list.add("b");
list.add("c");
System.out.println(list); // [a, b, c]
System.out.println("===========");
// void add(int index,E element):在此集合中的指定位置插入指定的元素
list.add(2,"g");
System.out.println(list); // [a, b, g, c]
System.out.println("===========");
// E remove(int index): 删除指定索引处的元素,返回被删除的元素
String remove = list.remove(2);
System.out.println("被删除的元素为:" + remove); // 被删除的元素为:g
System.out.println(list); // [a, b, c]
System.out.println("===========");
// E set(int index,E element): 修改指定索引处的元素,返回被修改的元素
String q = list.set(0, "q");
System.out.println("被修改的元素为:"+ q); // 被修改的元素为:a
System.out.println(list); // [q, b, c]
System.out.println("===========");
// E get(int index) :返回指定索引处的元素
String s = list.get(1);
System.out.println("指定的元素为:" + s); // 指定的元素为:b
System.out.println(list); // [q, b, c]
}
}
5.3 ArrayList集合特有方法
对于元素的操作,基本体现在——增、删、查。常用的方法有:
- public boolean add(E e) :将指定的元素添加到此集合的尾部。
- public E remove(int index) :移除此集合中指定位置上的元素。返回被删除的元素。
- public E get(int index) :返回此集合中指定位置上的元素。返回获取的元素。
- public int size() :返回此集合中的元素数。遍历集合时,可以控制索引范围,防止越界。
代码如下:
package collection;
import java.util.ArrayList;
/**
* @ClassName: Demo02ArrayList.class
* @Description:
* @Author: 喆
* @Date: 2022/6/8 19:55
* @Software: IntelliJ IDEA
**/
public class Demo02ArrayList {
/*
public boolean add(E e) :将指定的元素添加到此集合的尾部。
public E remove(int index) :移除此集合中指定位置上的元素。返回被删除的元素。
public E get(int index) :返回此集合中指定位置上的元素。返回获取的元素。
public int size() :返回此集合中的元素数。遍历集合时,可以控制索引范围,防止越界。
*/
public static void main(String[] args) {
// 创建一个ArrayList集合
ArrayList<Integer> list = new ArrayList<>();
// 往集合中元素
list.add(520);
list.add(521);
list.add(1314);
System.out.println(list); // [520, 521, 1314]
System.out.println("=================");
// public boolean add(E e) :将指定的元素添加到此集合的尾部。
list.add(1314521);
System.out.println(list); // [520, 521, 1314, 1314521]
System.out.println("=================");
// public E remove(int index) :移除此集合中指定位置上的元素。返回被删除的元素。
Integer remove = list.remove(1);
System.out.println("被删除的元素为:" + remove); // 被删除的元素为:521
System.out.println(list); // [520, 1314, 1314521]
System.out.println("=================");
// public E get(int index) :返回此集合中指定位置上的元素。返回获取的元素。
Integer c1 = list.get(0);
System.out.println("返回获取的元素为:" +c1); // 返回获取的元素为:520
System.out.println(list); // [520, 1314, 1314521]
System.out.println("=================");
// public int size() :返回此集合中的元素数。遍历集合时,可以控制索引范围,防止越界。
int size = list.size();
System.out.println("集合的元素为:" + size); // 集合的元素为:3
System.out.println(list); // [520, 1314, 1314521]
}
}
5.4 LinkedList
- public void addFirst(E e) :将指定元素插入此列表的开头。
- public void addLast(E e) :将指定元素添加到此列表的结尾。
- public E getFirst() :返回此列表的第一个元素。
- public E getLast() :返回此列表的最后一个元素。
- public E removeFirst() :移除并返回此列表的第一个元素。
- public E removeLast() :移除并返回此列表的最后一个元素。
- public E pop() :从此列表所表示的堆栈处弹出一个元素。
- public void push(E e) :将元素推入此列表所表示的堆栈。
- public boolean isEmpty() :如果列表不包含元素,则返回true。
代码如下:
package collection;
import java.util.LinkedList;
/**
* @ClassName: Demo03LinkedList.class
* @Description:
* @Author: 喆
* @Date: 2022/6/8 20:07
* @Software: IntelliJ IDEA
**/
public class Demo03LinkedList {
/*
public void addFirst(E e) :将指定元素插入此列表的开头。
public void addLast(E e) :将指定元素添加到此列表的结尾。
public E getFirst() :返回此列表的第一个元素。
public E getLast() :返回此列表的最后一个元素。
public E removeFirst() :移除并返回此列表的第一个元素。
public E removeLast() :移除并返回此列表的最后一个元素。
public E pop() :从此列表所表示的堆栈处弹出一个元素。
public void push(E e) :将元素推入此列表所表示的堆栈。
public boolean isEmpty() :如果列表不包含元素,则返回true。
*/
public static void main(String[] args) {
// 创建一个LinkedList集合
LinkedList<String> linkedList = new LinkedList<>();
// 往集合中添加元素
linkedList.add("苍老师");
linkedList.add("王老师");
linkedList.add("刘老师");
System.out.println(linkedList); //[苍老师, 王老师, 刘老师]
System.out.println("================");
// public void addFirst(E e) :将指定元素插入此列表的开头。
linkedList.addFirst("井田惠子");
System.out.println(linkedList); // [井田惠子, 苍老师, 王老师, 刘老师]
System.out.println("================");
// public void addLast(E e) :将指定元素添加到此列表的结尾。
linkedList.addLast("焦某");
System.out.println(linkedList); // [井田惠子, 苍老师, 王老师, 刘老师, 焦某]
System.out.println("================");
// public E getFirst() :返回此列表的第一个元素。
String first = linkedList.getFirst();
System.out.println("返回第一个元素为:" + first); // 返回第一个元素为:井田惠子
System.out.println(linkedList); // [井田惠子, 苍老师, 王老师, 刘老师, 焦某]
System.out.println("================");
String last = linkedList.getLast();
System.out.println("返回最后一个元素为:" + last); // 返回最后一个元素为:焦某
System.out.println(linkedList); // [井田惠子, 苍老师, 王老师, 刘老师, 焦某]
System.out.println("=================");
// public E removeFirst() :移除并返回此列表的第一个元素。
String s = linkedList.removeFirst();
System.out.println("删除的第一个元素为:" + s); // 删除的第一个元素为:井田惠子
System.out.println(linkedList); // [苍老师, 王老师, 刘老师, 焦某]
System.out.println("=================");
String l = linkedList.removeLast();
System.out.println("删除的最后一个元素为:" + l); // 删除的最后一个元素为:焦某
System.out.println(linkedList); // [苍老师, 王老师, 刘老师]
System.out.println("================");
// public E pop() :从此列表所表示的堆栈处弹出一个元素。
String pop = linkedList.pop();
System.out.println("弹出的元素为:" + pop); // 弹出的元素为:苍老师
System.out.println(linkedList); // [王老师, 刘老师]
System.out.println("================");
// public void push(E e) :将元素推入此列表所表示的堆栈。
linkedList.push("哈哈");
System.out.println("推入的元素为:" + linkedList); // 推入的元素为:[哈哈, 王老师, 刘老师]
System.out.println(linkedList); // [哈哈, 王老师, 刘老师]
System.out.println("=============");
// public boolean isEmpty() :如果列表不包含元素,则返回true。
boolean empty = linkedList.isEmpty();
System.out.println(empty); // false
System.out.println(linkedList); // [哈哈, 王老师, 刘老师]
}
}
六、Set集合
java.util.Set 接口和 java.util.List 接口一样,同样继承自 Collection 接口,它与 Collection 接口中的方 法基本一致,并没有对 Collection 接口进行功能上的扩充,只是比 Collection 接口更加严格了。与 List 接口不 同的是, Set 接口中元素无序,并且都会以某种规则保证存入的元素不出现重复
Set 集合有多个子类,这里我们介绍其中的 java.util.HashSet 、java.util.TreeSet、 java.util.LinkedHashSet 这三个集合。
tips:Set集合取出元素的方式可以采用:迭代器、增强for。
6.1 Set集合的概述和特点
- 不可以存储重复元素
- 没有索引,不能使用普通for循环遍历
6.2 Set集合的使用
代码如下:
package collection;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
/**
* @ClassName: Demo01Set.class
* @Description: 存储字符串并遍历
* @Author: 喆
* @Date: 2022/6/8 23:11
* @Software: IntelliJ IDEA
**/
public class Demo01Set {
public static void main(String[] args) {
// 创建集合对象
Set<String> set = new TreeSet<>();
// 往集合中添加元素
set.add("张三");
set.add("李四");
set.add("王五");
// 因为Set集合没有索引,所以不能通过索引来获取元素
/*
for (int i = 0; i < set.size(); i++) {
System.out.println(i);
}
*/
System.out.println(set); // [张三, 李四, 王五]
System.out.println("====================");
// 遍历集合
// 使用迭代器遍历
Iterator<String> it = set.iterator();
while (it.hasNext()){ //
String next = it.next();
System.out.println(next + ","); // 张三,李四,王五,
}
System.out.print("==================");
// 使用增强for循序进行遍历
for ( String str : set){
System.out.print(str);
}
}
}
6.3 TreeSet集合
6.3.1 TreeSet集合概述和特点
- 不可以存储重复元素
- 没有索引
- 可以将元素按照规则进行排序
- TreeSet():根据其元素的自然排序进行排序
- TreeSet(Comparator comparator) :根据指定的比较器进行排序
6.3.2 TreeSet集合基本使用
代码如下:
package collection;
import java.util.Iterator;
import java.util.TreeSet;
/**
* @ClassName: Demo01TreeSet.class
* @Description: 存储Integer类型的整数并遍历
* @Author: 喆
* @Date: 2022/6/9 11:30
* @Software: IntelliJ IDEA
**/
public class Demo01TreeSet {
public static void main(String[] args) {
// 创建TreeSet集合
TreeSet<Integer> treeSet = new TreeSet<>();
// 往集合中添加数据
treeSet.add(147);
treeSet.add(258);
treeSet.add(369);
System.out.println("集合中的元素为:" + treeSet);
System.out.println("======================");
// 增强for遍历集合
for (Integer i : treeSet){
System.out.println("遍历后的集合为:" + i);
}
// 使用迭代器进行遍历
Iterator<Integer> iterator = treeSet.iterator();
while (iterator.hasNext()){
Integer next = iterator.next();
System.out.println("迭代器遍历的集合为:"+next);
}
}
}
6.4 HashSet集合
6.4.1 HashSet集合概述和特点
- 底层数据结构是哈希表
- 存取无序
- 不可以存储重复元素
- 没有索引,不能使用普通for循环遍历
6.4.2 HashSet集合的基本应用
代码如下:
package collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
/**
* @ClassName: Demo01HashSet.class
* @Description: 存储字符串并遍历
* @Author: 喆
* @Date: 2022/6/9 11:46
* @Software: IntelliJ IDEA
**/
public class Demo01HashSet {
public static void main(String[] args) {
// 创建HashSet集合
HashSet<String> hashSet = new HashSet<>();
// 往集合中添加元素
hashSet.add("java");
hashSet.add("javaweb");
hashSet.add("mysql");
// 不包含重复元素
hashSet.add("java");
System.out.println("集合中的元素为:" + hashSet);
// 使用for循环进行遍历
for (String s : hashSet){
System.out.println("增强for循环遍历的集合为:" + s);
}
// 使用迭代器进行遍历
Iterator<String> iterator = hashSet.iterator();
while (iterator.hasNext()){
String next = iterator.next();
System.out.println("迭代器遍历的集合为:"+next);
}
}
}
6.4.3 HashSet存储自定义对象
- 案例需求
- 创建一个存储学生对象的集合,存储多个学生对象,使用程序实现在控制台遍历该集合
- 要求:学生对象的成员变量值相同,我们就认为是同一个对象
- 代码实现:
学生类
package collection;
import java.util.Objects;
/**
* @ClassName: Student.class
* @Description: 学生类
* @Author: 喆
* @Date: 2022/6/9 11:53
* @Software: IntelliJ IDEA
**/
public class Student {
/* 成员变量 */
private String name; /* 姓名 */
private int age; /* 年龄 */
/* 无参构造 */
public Student() {
super();
}
/* 有参构造 */
public Student(String name, int age) {
this.name = name;
this.age = age;
}
/* get、set方法 */
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
/* toString方法 */
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Student student = (Student) o;
return age == student.age && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
测试类
package collection;
import java.util.HashSet;
/**
* @ClassName: Demo02HashSet.class
* @Description: 测试类
* @Author: 喆
* @Date: 2022/6/9 11:57
* @Software: IntelliJ IDEA
**/
public class Demo02HashSet {
public static void main(String[] args) {
// 创建HashSet集合
HashSet<Student> set = new HashSet<>();
// 创建学生对象
Student s1 = new Student("张三", 20);
Student s2 = new Student("李四", 40);
Student s3 = new Student(" 王五", 30);
Student s4 = new Student("张三", 20);
// 往集合中添元素
set.add(s1);
set.add(s2);
set.add(s3);
set.add(s4);
// 此时可以存储重复元素(在没有重写hashCode方法和equals方法之前)
// 增强for循环
for (Student stu : set){
System.out.println(stu);
}
// 重写之后的结果(不允许出现的重复的值)
// Student{name='张三', age=20}
// Student{name='李四', age=40}
// Student{name=' 王五', age=30}
// 此时可以存储重复元素(在没有重写hashCode方法和equals方法之前的输出结果)
// Student{name=' 王五', age=30}
// Student{name='李四', age=40}
// Student{name='张三', age=20}
// Student{name='张三', age=20}
}
}
- 总结
- HashSet集合存储自定义类型元素,要想实现元素的唯一,要求必须重写hashCode方法和equals方法
七、Map集合
7.1 Map集合概述和特点
- Map集合的概述
interface Map<K,V> K:键的类型 V:值的类型
- Map集合的特点
- 双列集合,一个键一个值
- 键不可以重复,值可以重复
- Map集合的基本应用
package dmap;
import java.util.HashMap;
import java.util.Map;
/**
* @ClassName: MapDemo01.class
* @Description: Map集合的基本应用
* @Author: 喆
* @Date: 2022/6/9 12:24
* @Software: IntelliJ IDEA
**/
public class MapDemo01 {
public static void main(String[] args) {
// 创建集合对象
Map<String, String> map = new HashMap<>();
// V put(K key, V value) 将指定的值与该映射中的指定键相关联
map.put("scy01","老张");
map.put("scy02","老李");
map.put("scy03","老刘");
map.put("scy04","老六");
// 打印输出 (从输出结果看,map集合是无序的)
System.out.println(map); // {scy02=老李, scy01=老张, scy04=老六, scy03=老刘}
}
}
7.2 Map集合的基本功能
- 方法介绍
方法名 | 说明 |
V put(K key,V value) | 添加元素 |
V remove(Object key) | 根据键删除键值对元素 |
void clear() | 移除所有的键值对元素 |
boolean containsKey(Object key) | 判断集合是否包含指定的键 |
boolean containsValue(Object value) | 判断集合是否包含指定的值 |
boolean isEmpty() | 判断集合是否为空 |
int size() | 集合的长度,也就是集合中键值对的个数 |
- 代码展示
package dmap;
import java.util.HashMap;
import java.util.Map;
/**
* @ClassName: MapDemo02.class
* @Description:
* @Author: 喆
* @Date: 2022/6/9 12:33
* @Software: IntelliJ IDEA
**/
public class MapDemo02 {
public static void main(String[] args) {
// 创建集合对象
Map<String, String> map = new HashMap<String, String>();
// V put(K key,V value):添加元素
map.put("杨过","小龙女");
map.put("黄晓明","杨颖");
map.put("郭靖","黄蓉");
System.out.println("添加的元素为:" +map); // 添加的元素为:{杨过=小龙女, 郭靖=黄蓉, 黄晓明=杨颖}
System.out.println("=======================");
// V remove(Object key):根据键删除键值对元素
String s1 = map.remove("郭靖");
System.out.println("被删除的元素:"+s1); // 被删除的元素:黄蓉
System.out.println("删除后集合的元素为:" +map); // 删除后集合的元素为:{杨过=小龙女, 黄晓明=杨颖}
System.out.println("===================");
// void clear():移除所有的键值对元素
// map.clear();
System.out.println("集合的元素被清空:"+map); // 集合的元素被清空:{}
System.out.println("===================");
// boolean containsKey(Object key):判断集合是否包含指定的键
boolean b1 = map.containsKey("黄晓明");
System.out.println("指定的键是否被包含:"+ b1); // 指定包含的键为:true
boolean b2 = map.containsKey("郭靖");
System.out.println("指定的键是否被包含:"+ b2); // 指定的键是否被包含:false
System.out.println("===================");
// boolean isEmpty():判断集合是否为空
boolean empty = map.isEmpty();
System.out.println("集合是否为空:" +empty); // 集合是否为空:false
System.out.println("此时集合的元素有:"+map); // 此时集合的元素有:{杨过=小龙女, 黄晓明=杨颖}
System.out.println("===================");
// int size():集合的长度,也就是集合中键值对的个数
int size = map.size();
System.out.println("集合的长度为:"+size); // 集合的长度为:2
// 输出集合对象
System.out.println(map); // {杨过=小龙女, 黄晓明=杨颖}
}
}
7.3 Map集合的获取功能
- 方法介绍
方法名 | 说明 |
V get(Object key) | 根据键获取值 |
Set keySet() | 获取所有键的集合 |
Collection values() | 获取所有值的集合 |
Set> entrySet() | 获取所有键值对对象的集合 |
- 代码演示
package dmap;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* @ClassName: MapDemo03.class
* @Description:
* @Author: 喆
* @Date: 2022/6/9 12:59
* @Software: IntelliJ IDEA
**/
public class MapDemo03 {
public static void main(String[] args) {
// 创建集合对象
Map<String, String> map = new HashMap<String, String>();
// 添加元素
map.put("张无忌", "赵敏");
map.put("郭靖", "黄蓉");
map.put("杨过", "小龙女");
// V get(Object key):根据键获取值
System.out.println(map.get("张无忌")); // 赵敏
System.out.println(map.get("张三丰")); // null
System.out.println("=======================");
// Set<K> keySet():获取所有键的集合
Set<String> keySet = map.keySet();
for (String key : keySet) {
System.out.println(key);
}
System.out.println("=============");
// Collection<V> values():获取所有值的集合
Collection<String> values = map.values();
for (String value : values) {
System.out.println(value);
}
}
}
7.4 Map集合的遍历(方式1)
- 遍历思路
- 我们刚才存储的元素都是成对出现的,所以我们把Map看成是一个夫妻对的集合
- 把所有的丈夫给集中起来
- 遍历丈夫的集合,获取到每一个丈夫
- 遍历丈夫的集合,获取到每一个丈夫
- 我们刚才存储的元素都是成对出现的,所以我们把Map看成是一个夫妻对的集合
- 步骤分析
- 获取所有键的集合。用keySet()方法实现
- 遍历键的集合,获取到每一个键。用增强for实现
- 根据键去找值。用get(Object key)方法实现
- 代码演示
package dmap;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* @ClassName: MapDemo04.class
* @Description:
* @Author: 喆
* @Date: 2022/6/9 13:07
* @Software: IntelliJ IDEA
**/
public class MapDemo04 {
public static void main(String[] args) {
//创建集合对象
Map<String, String> map = new HashMap<String, String>();
//添加元素
map.put("张无忌", "赵敏");
map.put("郭靖", "黄蓉");
map.put("杨过", "小龙女");
//获取所有键的集合。用keySet()方法实现
Set<String> keySet = map.keySet();
//遍历键的集合,获取到每一个键。用增强for实现
for (String key : keySet) {
//根据键去找值。用get(Object key)方法实现
String value = map.get(key);
System.out.println(key + "," + value);
}
}
}
7.5 Map集合的遍历(方式2)
- 遍历思路
- 我们刚才存储的元素都是成对出现的,所以我们把Map看成是一个夫妻对的集合
- 获取所有结婚证的集合
- 获取所有结婚证的集合
- 根据结婚证获取丈夫和妻子
- 我们刚才存储的元素都是成对出现的,所以我们把Map看成是一个夫妻对的集合
- 步骤分析
- 获取所有键值对对象的集合
- 获取所有键值对对象的集合
- 遍历键值对对象的集合,得到每一个键值对对象
- 用增强for实现,得到每一个Map.Entry
- 根据键值对对象获取键和值
- 用getKey()得到键
- 用getValue()得到值
- 获取所有键值对对象的集合
- 代码展示
package dmap;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* @ClassName: MapDemo05.class
* @Description:
* @Author: 喆
* @Date: 2022/6/9 13:12
* @Software: IntelliJ IDEA
**/
public class MapDemo05 {
public static void main(String[] args) {
// 创建集合对象
Map<String, String> map = new HashMap<String, String>();
// 添加元素
map.put("张无忌", "赵敏");
map.put("郭靖", "黄蓉");
map.put("杨过", "小龙女");
// 获取所有键值对对象的集合
Set<Map.Entry<String, String>> entrySet = map.entrySet();
// 遍历键值对对象的集合,得到每一个键值对对象
for (Map.Entry<String, String> me : entrySet) {
// 根据键值对对象获取键和值
String key = me.getKey();
String value = me.getValue();
System.out.println(key + "," + value);
}
}
}
7.6 HashMap集合
7.6.1 1HashMap集合概述和特点
- HashMap底层是哈希表结构的
- 依赖hashCode方法和equals方法保证键的唯一
- 如果键要存储的是自定义对象,需要重写hashCode和equals方法
7.6.2 HashMap集合应用案例
- 案例需求
- 创建一个HashMap集合,键是学生对象(Student),值是居住地 (String)。存储多个元素,并遍历。
- 要求保证键的唯一性:如果学生对象的成员变量值相同,我们就认为是同一个对象
- 代码演示
学生类
package dmap;
/**
* @ClassName: Student.class
* @Description:
* @Author: 喆
* @Date: 2022/6/9 13:18
* @Software: IntelliJ IDEA
**/
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Student student = (Student) o;
if (age != student.age) {
return false;
}
return name != null ? name.equals(student.name) : student.name == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
}
测试类
package dmap;
import java.util.HashMap;
import java.util.Set;
/**
* @ClassName: HashMapDemo.class
* @Description:
* @Author: 喆
* @Date: 2022/6/9 13:19
* @Software: IntelliJ IDEA
**/
public class HashMapDemo {
public static void main(String[] args) {
// 创建HashMap集合对象
HashMap<Student, String> hm = new HashMap<Student, String>();
// 创建学生对象
Student s1 = new Student("林青霞", 30);
Student s2 = new Student("张曼玉", 35);
Student s3 = new Student("王祖贤", 33);
Student s4 = new Student("王祖贤", 33);
// 把学生添加到集合
hm.put(s1, "西安");
hm.put(s2, "武汉");
hm.put(s3, "郑州");
hm.put(s4, "北京");
// 遍历集合
Set<Student> keySet = hm.keySet();
for (Student key : keySet) {
String value = hm.get(key);
System.out.println(key.getName() + "," + key.getAge() + "," + value);
}
}
}
7.7 TreeMap集合
7.7.1 TreeMap集合概述和特点
- TreeMap底层是红黑树结构
- 依赖自然排序或者比较器排序,对键进行排序
- 如果键存储的是自定义对象,需要实现Comparable接口或者在创建TreeMap对象时候给出比较器排序规则
7.7.2 TreeMap集合应用案例一
- 案例需求
- 创建一个TreeMap集合,键是学生对象(Student),值是籍贯(String),学生属性姓名和年龄,按照年龄进行排序 并遍历
- 要求按照学生的年龄进行排序,如果年龄相同则按照姓名进行排序
- 代码实现
学生类
package dmap;
import java.util.logging.XMLFormatter;
/**
* @ClassName: Student.class
* @Description:
* @Author: 喆
* @Date: 2022/6/9 13:18
* @Software: IntelliJ IDEA
**/
public class Student implements Comparable<Student> {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Student o) {
// 按照年龄进行排序
int result = o.getAge() - this.getAge();
// 次要条件,按照姓名排序。
result = result == 0 ? o.getName().compareTo(this.getName()) : result;
return result;
}
}
测试类
package dmap;
import java.util.Set;
import java.util.TreeMap;
/**
* @ClassName: Test1.class
* @Description:
* @Author: 喆
* @Date: 2022/6/9 13:33
* @Software: IntelliJ IDEA
**/
public class Test1 {
private static Object Student;
public static void main(String[] args) {
// 创建TreeMap集合对象
TreeMap<Stu,String> tm = new TreeMap<>();
// 创建学生对象
Stu s1 = new Stu("xiaohei", 23);
Stu s2 = new Stu("dapang", 22);
Stu s3 = new Stu("xiaomei", 22);
// 将学生对象添加到TreeMap集合中
tm.put(s1, "江苏");
tm.put(s2, "北京");
tm.put(s3, "天津");
// 遍历TreeMap集合,打印每个学生的信息
Set<Stu> stus = tm.keySet();
for (Stu key : stus ){
String value = tm.get(key);
System.out.println(key);
}
}
}