Collection
# 前言
Java
集合可分为Collection
和Map
两种体系:
Collection
接口:单列数据,定义了存取一组对象的方法的集合List
:元素有序、可重复的集合ArrayList
、LinkedList
、Vector
Set
:元素无序、不可重复的集合HashSet
、LinkedHashSet
、TreeSet
Map
接口:双列数据,保存具有映射关系“key-value对
”的集合,也称为键值对。HashMap
、LinkedHashMap
、TreeMap
、Hashtable
、Properties
# 概述
Collection
接口是List
、Set
和Queue
的父接口,该接口里定义的方法既可用于操作Set
集合,也可用于操作List
和Queue
集合。
JDK不提供此接口的任何直接实现,而是提供更具体的子接口(如:Set
和List
)实现。
在Java5 之前,Java 集合会丢失容器中所有对象的数据类型,把所有对象都当成Object 类型处理;从JDK 5.0 增加了泛型以后,Java 集合可以记住容器中对象的数据类型。
# 接口方法
- 1、添加
add(Object obj)
:将obj对象添加到集合中。addAll(Collection coll)
:将另一个集合中的元素添加到当前的集合中。
- 2、获取有效元素的个数
int size()
- 3、清空集合
void clear()
- 4、是否是空集合
boolean isEmpty()
- 5、是否包含某个元素
boolean contains(Object obj)
:**是通过调用元素的equals
方法来判断是否是同一个对象。并不是比较内存地址,而是判断是否有相同数据的对象。**如果是自定义类并没有重写equals
方法,那么还是比较内存地址。会一直调用对象所在类的equals
方法,直到找到一个相同的才会返回。boolean containsAll(Collection c)
:也是调用元素的equals
方法来比较的。拿两个集合的元素挨个比较。与contains
方法不同的是,必须全部包含才返回true
,否则返回false
。
- 6、删除
boolean remove(Object obj)
:通过元素的equals
方法判断是否是要删除的那个元素。只会删除找到的第一个元素。boolean removeAll(Collection coll)
:也是调用元素的equals
方法,然后取当前集合的差集
- 7、取两个集合的交集
boolean retainAll(Collection c)
:也是调用元素的equals
方法,获取两个集合的交集,把交集的结果存在当前集合中,不影响形参集合c
- 8、集合是否相等
boolean equals(Object obj)
:也是调用元素的equals
方法,如果new
的是有序的集合,例如ArrayList
,还要顺序相同才会返回true
。
- 9、转成对象数组
Object[] toArray()
- 将数组转成集合:
Arrays.asList(T[] a)
- 注意:如果a不能是基本数据类,如果是基本数据类型,它会判断为一个对象,会将数组作为一个对象存进去,而不是将数组中每个元素存进去。
- 将数组转成集合:
- 10、获取集合对象的哈希值
hashCode()
- 11、遍历
iterator()
:返回迭代器对象,用于集合遍历
# Iterator
迭代器接口
# 概述
使用
Iterator
接口遍历集合元素
Iterator
对象称为迭代器(设计模式的一种),主要用于遍历Collection
集合中的元素。- GOF给迭代器模式的定义为:提供一种方法访问一个容器(
container
)对象中各个元素,而又不需暴露该对象的内部细节。迭代器模式,就是为容器而生。类似于“公交车上的售票员”、“火车上的乘务员”、“空姐”。 Collection
接口继承了java.lang.Iterable
接口,该接口有一个iterator()
方法,那么所有实现了Collection
接口的集合类都有一个iterator()
方法,用以返回一个实现了Iterator
接口的对象。Iterator
仅用于遍历集合,Iterator
本身并不提供承装对象的能力。如果需要创建Iterator
对象,则必须有一个被迭代的集合。- 集合对象每次调用
iterator()
方法都得到一个全新的迭代器对象,默认游标都在集合的第一个元素之前。
# Iterator
接口的方法
# 迭代器的执行原理
说明:假设当前集合有6个元素,当返回iterator
对象时,指针就放第一个元素之前,而iterator.next()
会将指针下移。在调用iterator.next()
方法之前必须要调用iterator.hasNext()
进行检测。若不调用,且下一条记录无效,直接调用iterator.next()
会抛出NoSuchElementException
异常。
注意:Iterator
对象不是一个容器,只是一个迭代器,它不装任何东西,只是用来遍历的。
# remove()
方法
Iterator
接口remove()
方法
注意:
Iterator
可以删除集合的元素,但是是遍历过程中通过迭代器对象的remove
方法,不是集合对象的remove
方法。- 如果还未调用
next()
或在上一次调用next()
方法之后已经调用了remove
方法,再调用remove
都会报IllegalStateException
。
# foreach
循环
使用
foreach
循环遍历集合元素
Java 5.0 提供了
foreach
循环迭代访问Collection
和数组。- 所以又称为增强for循环,原来的for循环称为普通for循环。
遍历操作不需获取
Collection
或数组的长度,无需使用索引访问元素。遍历集合的底层调用
Iterator
完成操作。foreach
还可以用来遍历数组。
# 练习
判断输出结果为何?
public class CollectionTest {
public static void main(String[] args) {
String[] str = new String[5];
for (String s : str) {
s = "java";
System.out.println("s = " + s);
}
for (int i = 0; i < str.length; i++) {
System.out.println("str[i] = " + str[i]);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
输出结果:
s = java
s = java
s = java
s = java
s = java
str[i] = null
str[i] = null
str[i] = null
str[i] = null
str[i] = null
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
为什么?
因为增强for循环是每次新建一个引用s,当你在增强for循环内对引用s重新赋值时,只会改变引用s的值,原来数组中的值并不会改变。如果想要改变原来数组中的值,请用普通for循环。
帮我改善此页面 (opens new window)
上次更新: 2020/12/27, 04:42:52