集合是一种存储空间可变的存储模型,它与数组的最大区别是它的存储空间是可变的,数组在初始化时就要确定好它的存储空间大小。但集合只能用于存储引用数据类型的对象,如要存储基本数据类型可以存储基本数据类型的包装类,而数组既可以存储基本数据类型也可以存储引用数据类型。
集合的体系结构:
其中集合主要分为单列集合和双列集合
单列集合:的每一个元素存储着一个数据,其中Collection是单列集合的根接口
双列集合:的每一个元素存储着一对数据,其中Map是双列集合的根接口
1、Collection
collection是单列集合的顶层接口,定义的是所有单列集合共有的功能,作为接口不能直接实例化,只能通过多态的方式提通过子类进行实例化
1.1 常用方法
方法名 | 说明 |
---|---|
boolean add(E e) | 添加元素 |
boolean remove(Object o) | 从集合中移除指定的元素 |
void clear() | 清空集合中的元素 |
boolean contains(Object o) | 判断集合中是否存在指定的元素 |
boolean isEmpty() | 判断集合是否为空 |
int size() | 集合的长度,也就是集合中元素的个数 |
因为Collection是所有单列集合的顶层接口,所以所有的单列集合实现类都可以直接使用这些方法
1.2 遍历集合
通常使用迭代器来遍历集合,
使用 Iterator<E> iterator() 返回集合的元素迭代器,因为需要使用集合来调用iterator()方法,所有迭代器是依赖于集合而存在的。
例:
public static void main(String[] args) {
//创建集合对象
Collection<String> c = new ArrayList<>();
//添加元素
c.add("hello");
c.add("world");
c.add("java");
c.add("javase");
c.add("javaweb");
//Iterator<E> iterator():返回此集合中元素的迭代器,通过集合的iterator()方法得到
Iterator<String> it = c.iterator();
//用while循环改进元素的判断和获取
while (it.hasNext()) {
String s = it.next();
System.out.println(s);
}
}
2、List集合
List是Collection的子接口,具有索引,可以通过索引来访问集合中的元素
特点:有索引、可以存储重复元素、元素存取有序
2.1 List的特有方法
除了继承于Collection的方法外,List集合还具有以下特有的方法,均与List具有索引的特点有关
2.2 List集合的遍历方式
List集合因为具有索引这个特点,即可以使用迭代器进行遍历集合,也可以通过普通的for循环,通过使用List的get(索引)的方法来获取集合中的元素。
例:
public class Dest {
public static void main(String[] args) {
ArrayList<A> arrayList = new ArrayList<>();
arrayList.add(new A(1));
arrayList.add(new A(2));
arrayList.add(new A(3));
for (int i=0;i<arrayList.size();i++){
System.out.println(arrayList.get(i).id);
}
}
}
class A{
int id;
public A(int id) {
this.id = id;
}
}
除此之外List集合还有一个特殊的迭代器ListIterator
在使用Iterator迭代器时,是不能进行修改操作的,如果进行修改操作会造成并发修改异常,而使用listIterator迭代器也可以对数据进行修改
例:iterator没有修改操作的方法如add()
public class Dest {
public static void main(String[] args) {
List<A> arrayList = new ArrayList<>();
arrayList.add(new A(1));
arrayList.add(new A(2));
arrayList.add(new A(3));
/*Iterator<A> iterator = arrayList.iterator();
while (iterator.hasNext()){
iterator.next();
iterator.add(new A(5));// 程序报错,iterator没有add这个方法
}*/
ListIterator<A> aListIterator = arrayList.listIterator();
while (aListIterator.hasNext()){
//System.out.println(aListIterator.next().id);
aListIterator.next();
aListIterator.add(new A(5));
}
for (A a : arrayList) {
System.out.println(a.id);
}
}
}
class A{
int id;
public A(int id) {
this.id = id;
}
}
2.3 List的实现类
Collection、List这些都只是接口,不能直接实例化,需要通过他们的实现类进行实例化,List常用的实现类有两个,分别是ArrayList和LinkList
ArrayList
存储方式:顺序存储,每个元素都是挨在一起存储的,空间是连续的
特点:参考数据结构中的顺序表,查找快(可以通过索引进行定位),增删慢(增删需要移 动大量的元素)
ArrayList的底层是通过数组实现的,通过判断数组是否存储满了,如果存储满了就创建一个1.5倍长的新数组,将原数组的内容拷贝给这个新数组,从而实现数组的扩容。
LinkList
存储方式:链式存储,不是连续存储的。
特点:参考数据结构中的链表,查找慢,增删快。
LinkList的特有方法:
方法名 | 说明 |
---|---|
public void addFirst(E e) | 在该列表开头插入指定的元素 |
public void addLast(E e) | 将指定的元素追加到此列表的末尾 |
public E getFirst() | 返回此列表中的第一个元素 |
public E getLast() | 返回此列表中的最后一个元素 |
public E removeFirst() | 从此列表中删除并返回第一个元素 |
public E removeLast() | 从此列表中删除并返回最后一个元素 |
3、Set集合
set是collection的另一个子接口,它与List的主要区别在于元素不可重复
3.1 set集合的特点
元素存取无序
没有索引、只能通过迭代器或增强for循环遍历
不能存储重复元素
例:
public class SetDemo {
public static void main(String[] args) {
//创建集合对象
Set<String> set = new HashSet<String>();
//添加元素
set.add("hello");
set.add("world");
set.add("java");
//不包含重复元素的集合
set.add("world");
//遍历
for(String s : set) {
System.out.println(s);
}
}
}
3.2 set集合的实现类
3.2.1 HashSet
特点:
底层数据结构是哈希表
对集合的迭代顺序不作任何保证,也就是说不保证存储和取出的元素顺序一致
没有带索引的方法,所以不能使用普通for循环遍历
由于是Set集合,所以是不包含重复元素的集合
HashSet的基本使用:
public class Demo {
public static void main(String[] args) {
//创建集合对象
HashSet<String> hs = new HashSet<String>();
//添加元素
hs.add("hello");
hs.add("world");
hs.add("javaee");
hs.add("world");// 相同元素,不做存储
//遍历
for(String s : hs) {
System.out.println(s);
}
}
}
HashSet集合保证元素唯一性的原理
1. 根据对象的哈希值计算存储位置
如果当前位置没有元素则直接存入
如果当前位置有元素存在,则进入第二步
2. 当前元素的元素和已经存在的元素比较哈希值
如果哈希值不同,则将当前元素进行存储
如果哈希值相同,则进入第三步
3. 通过equals()方法比较两个元素的内容
如果内容不相同,则将当前元素进行存储
如果内容相同,则不存储当前元素
若要保证元素的存取有序,可以使用LinkedHashSet,通过使用哈希表和链表实现的Set接口,可以由链表保证元素有序,由哈希表保证元素唯一
3.2.2 TreeSet
特点:
元素有序,可以按照一定的规则进行排序,具体排序方式取决于构造方法
没有带索引的方法,所以不能使用普通for循环遍历
由于是Set集合,所以不包含重复元素的集合
当需要对一个集合进行排序是可以使用TreeSet
默认通过元素的自然排序进行排序,也可以通过重写Comparator自定义排序
4、Map集合
特点:
键值对映射关系
一个键对应一个值
键不能重复,值可以重复
元素存取无序
4.1 常用方法
方法名 | 说明 |
---|---|
V put(K key,V value) | 添加元素 |
V remove(Object key) | 根据键删除键值对元素 |
void clear() | 移除所有的键值对元素 |
boolean containsKey(Object key) | 判断集合是否包含指定的键 |
boolean containsValue(Object value) | 判断集合是否包含指定的值 |
boolean isEmpty() | 判断集合是否为空 |
int size() | 集合的长度,也就是集合中键值对的个数 |
基本使用:
public class Demo {
public static void main(String[] args) {
//创建集合对象
Map<String,String> map = new HashMap<String,String>();
//V put(K key, V value) 将指定的值与该映射中的指定键相关联
map.put("1","张三丰");
map.put("2","张无忌");
map.put("3","谢逊");
map.put("4","成昆");
//输出集合对象
System.out.println(map);
}
}