JAVA 集合类
目录
集合
一、集合的理解和好处
前面我们保存多个数据使用的是数组,那么数组有不足的地方
数组的不足之处:
- 长度开始时必须指定,而且一旦指定,不能更改
- 保存的必须为同意类型的元素
- 使用数组进行增加/删除 比较麻烦
集合的好处
- 可以动态保存任意多个对象,使用比较方便!
- 提供了一系列方便的操作对象的方法:
add、remove、set、get
等 - 使用集合添加、删除新元素的代码更加简洁了
二、集合框架图
要求:背下来
集合主要分为两组
- 单列集合:在集合中放的都是单个单个的元素
- 双列集合:剑字段一起存放
Collection
接口有两个重要的接口,List和Set,他们的实现子类都是单列集合- Map 接口的实现子类是双列集合,存放K-V
单列集合:Collection
双列集合:Map
package com.hspedu.collection_;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/**
* @author DL5O
* @version 1.0
*/
public class Collection_ {
@SuppressWarnings("all")
public static void main(String[] args) {
// Collection
// Map
ArrayList arrayList = new ArrayList();
arrayList.add("jack");
arrayList.add("tom");
HashMap hashMap = new HashMap();
hashMap.put("NO1","北京");
hashMap.put("NO2","伤害");
}
}
三、Collection接口和常用方法
1.Collection接口实现的特点
public interface Collection<E> extends Iterable<E>
- collection实现子类可以存放多个元素,每个元素可以是Object
- 有些Collection的实现类,可以存放重复的元素,有些不可以
- 有些Collection的实现类,有些是有序的(List),有些不是有序(Set)
- Collection接口没有直接的实现子类,是通过它的子接口Set和 List来实现的
2.Collection接口常用方法
package com.hspedu.collection_;
import java.util.ArrayList;
import java.util.List;
/**
* @author DL5O
* @version 1.0
*/
public class ArrayList_ {
@SuppressWarnings("all")
public static void main(String[] args) {
List list = new ArrayList();
//add 添加单个元素
list.add("jack");
list.add(10);//这里有个自动装箱的过程,会装箱为包装类,list.add(new Integer(10))
list.add(true);//同上
System.out.println("list=" + list);//list=[jack, 10, true]
//remove:删除指定元素
//list.remove(0);//删除第一个元素
//也可以
list.remove("jack");
System.out.println("list=" + list);
//contains:查找元素是否存在
System.out.println(list.contains(10));//T
//size:获取元素个数
System.out.println(list.size());//2
// isEmpty:判断是否为空
System.out.println(list.isEmpty());//F
// clear:清空
// list.clear();
// System.out.println("list=" + list);//list=[]
// addAll:添加多个元素
ArrayList list2 = new ArrayList();
list2.add("红楼梦");
list2.add("三国演义");
list.addAll(list2);
System.out.println("list=" + list);
// containsAll:查找多个元素是否都存在
System.out.println(list.containsAll(list2));//T
// removeAll:删除多个元素
list.add("聊斋");
list.removeAll(list2);
System.out.println("list=" + list);//[10, true, 聊斋]
}
}
3.Collection 接口遍历元素方式 1-使用 Iterator(迭代器)
介绍:只要是实现了Collection接口的子类都可以获取到Iterator这个迭代器,然后用这个迭代器遍历这个集合的所有元素
-
Iterator对象称为迭代器,主要用于遍历Collection集合中的元素
-
Collection接口的集合类都有一个iterator()方法,用来返回一个实现了Iterator接口的对象,即返回一个迭代器
-
Iterator的执行原理
-
得到一个数组,从栈顶开始依次下移指针,直到栈底
-
next()的作用:
- 下移
- 将下移以后集合位置上的元素返回
Iterator(迭代器遍历)
注意:
- 在调用
iterator.next()
方法之前必须要调用iterator.hasNext()
进行检测。若不调用,且下一条记录无效,直接调用it.next(
)会抛出异常。
package com.hspedu.collection_;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* @author DL5O
* @version 1.0
*/
@SuppressWarnings("all")
public class CollectionIterator01 {
public static void main(String[] args) {
Collection col = new ArrayList();
col.add(new Book("三国演义", "罗贯中", 10.1));
col.add(new Book("小李飞刀", "古龙", 5.1));
col.add(new Book("红楼梦", "曹雪芹", 34.6));
col.add("jack");
// System.out.println("col" + col);
//现在想一本一本的遍历这个 col 集合
//1.先得到这个集合对应的迭代器
Iterator iterator = col.iterator();
//2.使用while循环遍历
/*while (iterator.hasNext()) {//判断是否还有数据
//next方法返回的数据,是下一个元素,类型是Object,
//编译类型 Object
//运行类型 取决于真正存放的类型
Object obj = iterator.next();
System.out.println("obj=" + obj);
}*/
//快捷键,快速生成 ==> itit
//快捷键提示 ctrl + j
while (iterator.hasNext()) {
Object next = iterator.next();
System.out.println("obj=" + next);
}
//3.当退出while循环后,这时iterator迭代器,指向的是最后的元素
//iterator.next();//报异常:NoSuchElementException
//4.如果需要再次遍历,需要重置迭代器
System.out.println("====第二次====");
iterator = col.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
System.out.println("obj=" + next);
}
}
}
@SuppressWarnings("all")
class Book {
private String name;
private String author;
private double price;
public Book(String name, String author, double price) {
this.name = name;
this.author = author;
this.price = price;
}
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;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
", price=" + price +
'}';
}
}
for 循环增强遍历
基本语法:
for(元素类型 元素名:集合或数组名){
访问元素
}
package com.hspedu.collection_;
import java.util.ArrayList;
import java.util.Collection;
/**
* @author DL5O
* @version 1.0
*/
public class CollectionFor01 {
@SuppressWarnings({"all"})
public static void main(String[] args) {
Collection col = new ArrayList();
col.add(new Book("三国演义", "罗贯中", 10.1));
col.add(new Book("小李飞刀", "古龙", 5.1));
col.add(new Book("红楼梦", "曹雪芹", 34.6));
//使用增强for循环
//1.使用增强for,在Collection集合
//2.增强for,底层仍然是迭代器
//3.可以理解成:简化版的迭代器遍历
//快捷键 I
for (Object o :col) {
System.out.println(o);
}
//增强for可以用在数组上
int[] nums = {1, 23, 4, 5};
for (int i : nums) {
System.out.print(i + " ");
}
}
}
快捷键:大写的I
四、List接口和常用方法
- List集合类中的元素是有序的(添加顺序和取出顺序一致)、且可重复
- List 集合中的每个元素都有其对应的顺序索引,即支持索引
- List接口常用的是
ArrayList
、LinkedList
和Vector
package com.hspedu.list_;
import java.util.ArrayList;
import java.util.List;
/**
* @author DL5O
* @version 1.0
*/
public class ListMethod {
public static void main(String[] args) {
List list = new ArrayList();
list.add("张三丰");
list.add("贾宝玉");
// void add(int index, Object ele):在 index 位置插入 ele 元素
//在 index = 1 的位置插入一个对象
list.add(1,"大龙");
System.out.println("list=" + list);
// boolean addAll(int index, Collection eles):从 index 位置开始将 eles 中的所有元素添加进来
List list2= new ArrayList();
list2.add("jack");
list2.add("tom");
list.addAll(1,list2);
list.add("大龙");
System.out.println("list=" + list);
//Object get(int index):获取指定 index 位置的元素
System.out.println("1 index element=" + list.get(1));//jack
//int indexOf(Object obj):返回 obj 在集合中首次出现的位置
System.out.println("大龙 index=" + list.indexOf("大龙"));//3
//int lastIndexOf(Object obj):返回 obj 在当前集合中末次出现的位置
System.out.println("大龙 lastIndex=:"+list.lastIndexOf("大龙"));//5
//Object remove(int index):移除指定 index 位置的元素,并返回此元素
list.remove("张三丰");
System.out.println("list=" + list);
//Object set(int index, Object ele):设置指定 index 位置的元素为 ele , 相当于是替换
list.set(1,"玛丽");
System.out.println("list=" + list);
//List subList(int fromIndex, int toIndex):返回从 fromIndex 到 toIndex 位置的子集合
// 注意:这里没有包索引为3的对象元素取到,所以返回的集合是[formIndex,toIndex);
List returnList = list.subList(1, 3);
System.out.println("returnList" + returnList);//[玛丽, 大龙]
}
}
1.List的三种遍历方法
package com.hspedu.list_;
import java.util.*;
/**
* @author DL5O
* @version 1.0
*/
public class ListFor {
@SuppressWarnings("all")
public static void main(String[] args) {
//接口实现的子类 LinkedList ArrayList Vector
List list = new Vector();
/* List list = new ArrayList();
List list = new LinkedList();*/
list.add("jack");
list.add("tom");
list.add("鱼香肉丝");
list.add("北京烤鸭");
//遍历
//1.使用iterator迭代器遍历
System.out.println("====使用iterator迭代器遍历====");
Iterator iterator = list.iterator();
while(iterator.hasNext()){
Object next = iterator.next();
System.out.println("obj=" + next);
}
//2.使用增强for循环进行遍历
// 底层仍然是实现了Iterator这个接口,然后进行相关方法的调用,相当于简化版的iterator迭代器
System.out.println("====使用增强for循环进行遍历====");
for (Object o :list) {
System.out.println("obj=" + o);
}
//3.使用普通的for
for (int i = 0; i < list.size(); i++) {
System.out.println("obj=" + list.get(i));
}
}
}
2.课堂练习
package com.hspedu.list_;
import java.util.ArrayList;
import java.util.List;
/**
* @author DL5O
* @version 1.0
*/
public class ListExercise01 {
public static void main(String[] args) {
List list = new ArrayList();
list.add(new Book("红楼梦", "曹雪芹", 100));
list.add(new Book("西游记", "吴承恩", 10));
list.add(new Book("水浒传", "施耐庵", 19));
list.add(new Book("三国", "罗贯中", 80));
System.out.println("====排序前====");
for (Object book : list) {
System.out.println(book);
}
sort(list);
System.out.println("====排序后====");
for (Object book : list) {
System.out.println(book);
}
}
//价格要求是从小到大
//利用list.set 实现集合元素的交换
public static void sort(List list) {
int listSize = list.size();
for (int i = 0; i < listSize - 1; i++) {
for(int j = 0 ; j < listSize - 1 - i;j++){
Book book1 = (Book)list.get(j);//取出来后的对象是Object类型的,因此这里要向下转型
Book book2 = (Book)list.get(j+1);
if(book1.getPrice() > book2.getPrice()){
list.set(j,book2);
list.set(j+1,book1);
}
}
}
}
}
@SuppressWarnings("all")
class Book {
private String name;
private String author;
private double price;
public Book(String name, String author, double price) {
this.name = name;
this.price = price;
this.author = author;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
@Override
public String toString() {
String formatstr= "名称:%s\t价格:%.2f\t作者:%s\t";
String info = String.format(formatstr,this.name,this.price,this.author);
return info;
}
}
五、Set接口和常用方法
Set接口介绍:
- 无序(添加和取出的顺序不一致),没有索引
- 不允许重复元素,所以最多包含一个null
- JDK API中Set接口实现的类又
1.Set接口的常用方法
- 和 List 接口一样, Set 接口也是 Collection 的子接口,因此,常用方法和 Collection 接口一样
2.Set接口的遍历方法
同Collection的遍历方法一样
- 可以使用迭代器
- 增强for
注意:
- 不能使用索引的方式来获取。
3.Set接口的常用方法
注意:
-
set接口的实现类对象(set接口对象),不能存放重复的元素
-
null
可以加入到集合中 -
set
接口对象存放数据是无序(即添加的顺序和取出的顺序不一致)的 -
取出的顺序的是固定的,虽然不是添加的顺序,但是它的固定的
package com.hspedu.set_;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
* @author DL5O
* @version 1.0
*/
public class SetMethod {
public static void main(String[] args) {
// 解读:
// 1.以 Set 接口的实现类 HashSet 来讲解 Set 接口的方法
// 2.set 接口的对象
Set set = new HashSet();
set.add("john");
set.add("lucy");
set.add("jahn");//重复
set.add("john");
set.add("ywl");
set.add("ywl");
set.add(null);//空
set.add(null);//再次添加空
System.out.println(set);//[null, john, jahn, lucy]
System.out.println(set);//[null, john, jahn, lucy]
//遍历
//方式一:使用迭代器
System.out.println("===迭代器遍历===");
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
Object obj = iterator.next();
System.out.println("obj=" + obj );
}
//方式二:增强for
System.out.println("===增强for===");
for (Object o :set) {
System.out.println("o=" + o);
}
}
}
六、如何选择集合实现类
- 先判断存储的类型(一组对象[单列]或一组键值对[双列])
- 一组对象[单列]:Collection接口
- 允许重复:
List
- 增删多:
LinkdList
[底层维护了一个双向链表] - 改查多:
ArrayList
[底层维护了Object类型的可变数组]
- 增删多:
- 不允许重复:
Set
- 无序:
HashSet
[底层 HashMap,维护的是一个哈希表即(数组+链表+红黑树)] - 排序:
TreeSet
- 插入和取出顺序一致:
LinkedHashSet
[底层LinkedHashMap的底层HashMap],维护的数组+双向链表
- 无序:
- 允许重复:
- 一组键值对:Map
- 键无序:
HashMap
[底层是:哈希表 jdk7:数组+链表 jdk8:数组+链表+红黑树] - 键排序:
TreeMap
- 键插入和取出顺序一致:
LinkedHashMap
- 读取文件:
Properties
- 键无序: