Java-09-集合
集合类概述
数组长度是固定,如果要改变数组的长度需要创建新的数组将旧数组里面的元素拷贝过去,使用起来不方便。
java给开发者提供了一些集合类,能够存储任意长度的对象,长度可以随着元素的增加而增加,随着元素的减少而减少,使用起来方便一些。
集合类的特点
集合 | 特定 |
---|---|
List | 有序,可重复 |
Set | 无序,不可重复 |
Queue | 队列(先进先出),可重复 |
集合vs数组
数组 | 集合 | |
---|---|---|
存储类型 | 基本数据类型(值),引用数据类型(地址值) | 仅 引用数据类型(对象),若存基本数据类型->自动装箱,包装类 |
长度 | 固定 | 可变,随元素的增加而自动增长 |
集合框架
Java集合类主要由两个根接口Collection和Map派生而来,Collection又派生出List,Set,Queue三个子接口,而Map集合存储的东西比较特殊,它提供的是key到value的映射,存储的是键值对的集合,所以Java集合可大致分为List
,Set
,Queue
,Map
四种接口体系,上图中蓝色背景覆盖的是集合体系中常用的实现类
以ArrayList,该实现类为例
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class TestSet {
public static void main(String[] args) {
// 要想使用集合,需要创建对象,集合框架中有大量的接口和抽象类
// 一些实现类能实例化集合对象
Collection c = new ArrayList();
//将字符串存入ArrayList集合中
c.add("h");
c.add("i");
//size获得集合大小
System.out.println(c.size());//2
//ArrayList重写了toString 方法,输出了内容,而不是地址
System.out.println(c);//[h, i]
//如何遍历集合?使用迭代器 iterator
//转数组遍历是不可取的,java提供了一个iterator的接口,在集合的实现类里都实现了这个接口
c.add("how are you?");
//while 的写法
Iterator it = c.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//for 的写法
for (Iterator it2 = c.iterator();it2.hasNext();){
System.out.println(it2.next());
}
}
}
1.List集合
有序,有下标,可重复
List接口继承了Collection接口,Collection集合中有的方法,List集合也有
ArrayList
import java.util.ArrayList;
public class TestList {
public static void main(String[] args) {
ArrayList list = new ArrayList();
//添加元素
list.add('h');
list.add('e');
list.add('l');
list.add('l');
list.add('o');
//访问元素
System.out.println(list.size());//集合大小,有多少数组 5
//list.get(i); 通过下标访问
for (int i= 0;i<list.size();i++){
System.out.println(list.get(i));
/*
* h
* e
* l
* l
* o
* */
}
//修改元素
list.set(1, "o"); // 第一个参数为索引位置,第二个为要修改的值
System.out.println(list);//[h, o, l, l, o]
//删除元素
list.remove(3); // 删除第四个元素
System.out.println(list);//[h, o, l, o]
}
}
方法 | 描述 |
---|---|
add | 将元素插入到指定位置的 arraylist 中 |
addAll | 添加集合中的所有元素到 arraylist 中 |
clear() | 删除 arraylist 中的所有元素 |
clone() | 复制一份 arraylist |
contains() | 判断元素是否在 arraylist |
get() | 通过索引值获取 arraylist 中的元素 |
indexOf() | 返回 arraylist 中元素的索引值 |
removeAll() | 删除存在于指定集合中的 arraylist 里的所有元素 |
remove() | 删除 arraylist 里的单个元素 |
size() | 返回 arraylist 里元素数量 |
isEmpty() | 判断 arraylist 是否为空 |
subList() | 截取部分 arraylist 的元素 |
set() | 替换 arraylist 中指定索引的元素 |
sort() | 对 arraylist 元素进行排序 |
toArray() | 将 arraylist 转换为数组 |
toString() | 将 arraylist 转换为字符串 |
ensureCapacity() | 设置指定容量大小的 arraylist |
lastIndexOf() | 返回指定元素在 arraylist 中最后一次出现的位置 |
retainAll() | 保留 arraylist 中在指定集合中也存在的那些元素 |
containsAll() | 查看 arraylist 是否包含指定集合中的所有元素 |
trimToSize() | 将 arraylist 中的容量调整为数组中的元素个数 |
removeRange() | 删除 arraylist 中指定索引之间存在的元素 |
replaceAll() | 将给定的操作内容替换掉数组中每一个元素 |
removeIf() | 删除所有满足特定条件的 arraylist 元素 |
forEach() | 遍历 arraylist 中每一个元素并执行特定操作 |
LinkList
作为线性表,易增删,不易查改
LinkedList和ArrayList用的时机
频繁访问列表中某一元素,只需在列表末尾进行增删操作,频繁的查询修改--------------------ArrayList
频繁进行添加,删除操作--------------------------------------------------------------------------------------LinkedList
import java.util.LinkedList;
public class TestLinkedList {
public static void main(String[] args) {
LinkedList ll = new LinkedList();
//添加元素
ll.add("hello");
ll.add("how");
ll.add("old");
ll.add("are");
ll.add("you");
System.out.println(ll);//LinkedList也重写了toString方法 [hello, how, old, are, you]
//在表头添加元素
ll.addFirst("oh!");
System.out.println(ll);//[oh!, hello, how, old, are, you]
//在表尾添加元素
ll.addLast("?");
System.out.println(ll);//[oh!, hello, how, old, are, you, ?]
//移除表头元素
ll.removeFirst();
System.out.println(ll);
//移除表尾元素
ll.removeLast();
System.out.println(ll);
//获取表头元素
System.out.println(ll.getFirst());
//也可以通过下标获取表中元素,效率慢~
System.out.println(ll.get(2));
//获取表尾元素
System.out.println(ll.getLast());
}
}
2.Set集合
无序,不可重复
HashSet
HashSet是Set接口的典型实现,大多数时候使用Set集合时就是使用这个实现类。HashSet按Hash算法来存储集合中的元素,因此具有很好的存取和查找性能。底层数据结构是哈希表。
特点
- 无序,不重复
- 不是线程安全的, 如果多个线程尝试同时修改 HashSet,则最终结果是不确定的。
- 允许有 null 值。
import java.util.HashSet;
public class TestHashSet {
public static void main(String[] args) {
HashSet<String> hashSet = new HashSet<String>();
// add方法添加元素
hashSet.add("Hello");
hashSet.add("My");
hashSet.add("name");
hashSet.add("is");
hashSet.add("Li Hua");
System.out.println(hashSet);//HashSet重写了toString 方法[Hello, Li Hua, name, is, My]
hashSet.add("Li Hua");//重复元素不被添加
System.out.println(hashSet);//[Hello, Li Hua, name, is, My]
//判断元素是否存在
System.out.println(hashSet.contains("name"));//true
//删除元素
hashSet.remove("Li Hua");//传具体要删的值
System.out.println(hashSet);//[Hello, name, is, My]
//使用foreach()遍历
for ( String s :hashSet){
System.out.println(s);
/*
* Hello
* name
* is
* My
* */
}
//全部删除
hashSet.clear();
System.out.println(hashSet);//[]
}
}
内部存储机制
当向HashSet集合中存入一个元素时,HashSet会调用该对象的hashCode方法来得到该对象的hashCode值,然后根据该hashCode值决定该对象在HashSet中的存储位置。如果有两个元素通过equals方法比较true,但它们的hashCode方法返回的值不相等,HashSet将会把它们存储在不同位置,依然可以添加成功。
也就是说。HashSet集合判断两个元素的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode方法返回值也相等。靠元素重写hashCode方法和equals方法来判断两个元素是否相等,如果相等则覆盖原来的元素,依此来确保元素的唯一性
3.Map集合
键值对集合
HashMap
- 是一个散列表,它存储的内容是键值对(key-value)映射。
- 实现现了 Map 接口,根据键的 HashCode 值存储数据,具有很快的访问速度,最多允许一条记录的键为 null,不支持线程同步。
- 无序
import java.util.HashMap;
public class TestHashMap {
public static void main(String[] args) {
HashMap hashMap = new HashMap();
//添加键值对,put关键字
hashMap.put(1,"hello");//数字:字符串
hashMap.put(2,"you");
hashMap.put(3,"are");
hashMap.put(4,"my");
hashMap.put(5,"friend");
hashMap.put(6,null);
System.out.println(hashMap);//HashMap重写了toString 方法{1=hello, 2=you, 3=are, 4=my, 5=friend, 6=null}
hashMap.put("seven","hahaha");//字符串:字符串
System.out.println(hashMap);//{1=hello, 2=you, 3=are, 4=my, 5=friend, 6=null, seven=hahaha}
hashMap.put(null,"test");
System.out.println(hashMap);//{null=test, 1=hello, 2=you, 3=are, 4=my, 5=friend, 6=null, seven=hahaha}
hashMap.put(null,"emm");//把之前的test覆盖了
System.out.println(hashMap);//{null=emm, 1=hello, 2=you, 3=are, 4=my, 5=friend, 6=null, seven=hahaha}
//访问元素 get(key)得到value
System.out.println(hashMap.get(null));//emm
System.out.println(hashMap.get(3));//are
System.out.println(hashMap.get("seven"));//hahaha
//删除元素 remove(key) 删除键值对
hashMap.remove(null);
System.out.println(hashMap);//{1=hello, 2=you, 3=are, 4=my, 5=friend, 6=null, seven=hahaha}
//删除所有 clear()
hashMap.clear();
System.out.println(hashMap);//{}
//遍历hashMap
HashMap<Integer,String> hashMap2 = new HashMap<Integer,String>();
hashMap2.put(1,"hello");//数字:字符串
hashMap2.put(2,"you");
hashMap2.put(3,"are");
hashMap2.put(4,"my");
hashMap2.put(5,"friend");
hashMap2.put(6,null);
// 输出 key 和 value
for (Integer i : hashMap2.keySet()) {
System.out.println("key: " + i + " value: " + hashMap2.get(i));
/*
key: 1 value: hello
key: 2 value: you
key: 3 value: are
key: 4 value: my
key: 5 value: friend
key: 6 value: null
*/
}
// 返回所有 value 值
for(String value: hashMap2.values()) {
// 输出每一个value
System.out.print(value + ", ");
//hello, you, are, my, friend, null,
}
}
}