集合是用来存放对象的容器。所有集合类都位于java.util包下,但支持多线程的集合类位于java.util.concurrent包下。
1、集合的概念
关于集合的定义,有以下三点注意:
- 集合只能存放对象。基本数据类型会进行自动装箱转化为对应的引用类型;
- 集合存放的都是对象的引用,而非对象本身。对象本身还是放在堆内存中;
- 集合可以存放多种类型,不限数量的数据类型。
集合与数组的区别:
- 数组的长度不可变化,且不能存放具有映射关系的数据(k-v);集合用来保存数量不确定的数据,且可以保存具有映射关系的数据;
- 数组既可以存放基本类型的数据,又可以存放对象;集合只能存放对象。
Java将一些具有相似属性和功能的数据结构抽象为一组公共的接口,Java的集合框架就是围绕这些标准接口进行设计的,你可以直接使用这些接口的标准实现,也可以通过这些接口实现自己的集合类。
2、Java集合框架
Java集合框架是由两个根接口:Collection接口和Map接口派生而来的。Collection接口派生出了三个子接口:List、Set、Queue,List接口有两个比较常用的实现类:ArrayList和LinkedList,Set接口有两个比较常用的实现类:HashSet和TreeSet,Queue的实现类也有LinkedList;Map接口有两个比较常用的实现类:HashMap和TreeMap,还有个不经常用的实现类:HashTable。注意的是Collection接口和Map接口也被抽象类AbstractList和AbstractMap实现,具体的实现类比如ArrayList在实现了List接口的同时也继承了AbstractList抽象类。
集合框架图如图所示,这里引用的是链接1中的图,注意图中忽略了抽象类AbstractList和AbstractMap。
3、迭代器Iterator
迭代器是用来遍历集合类的。上面讲的集合框架的两个根接口:Collection接口和Map接口,其中Collection接口又继承了更顶层的Iterable接口,Iterable接口里又封装了 Iterator 接口,源码如下:
public interface Iterable<T> {
/**
* Returns an iterator over elements of type {@code T}.
*
* @return an Iterator.
*/
Iterator<T> iterator();
...
}
Iterator 接口里包含了三个重要方法:
public interface Iterator<E> {
// 若被迭代的集合里还有元素没有被遍历,返回true.
boolean hasNext();
// 返回集合的下一个元素.
E next();
// 删除集合上一次next()方法返回的元素
default void remove() {
throw new UnsupportedOperationException("remove");
}
}
因此只要是实现了Collection接口的集合类,都可以调用Iterator迭代器遍历集合类,通用方法如下:
Iterator iter = l.iterator();
while(iter.hasNext()){
System.out.println(iter.next());
}
其中l为实现了Collection接口的集合类。
注意:Map接口并没有继承Iterable接口,因此实现了Map接口的类不能直接通过map.iterator()得到迭代器,需要将Map类通过map.entrySet()转化为Set集合类(实现了Collection接口),再通过set.iterator()使用迭代器。
3.1 用迭代器遍历Collection接口的实现类
以ArrayList为例,代码如下:
public class Demo {
public static void main(String[] args) {
List<Integer> myList = new ArrayList<Integer>();
for (int i = 0; i < 10; ++i)
{
myList.add(i);
}
Iterator iterator = myList.iterator();
while (iterator.hasNext())
{
System.out.println(iterator.next());
}
}
}
3.2 用迭代器遍历Map接口的实现类
以HashMap为例,代码如下:
public class Demo {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("Jerry", 1);
map.put("Cissie", 2);
// 通过entrySet()方法将map中的entry(k-v对)放入到set
Set<Map.Entry<String, Integer>> set = map.entrySet();
// 获得set的迭代器遍历set,相当于间接地遍历了map
Iterator iterator = set.iterator();
while (iterator.hasNext())
{
System.out.println(iterator.next());
}
}
}
参考
https://zhuanlan.zhihu.com/p/86578960
https://www.cnblogs.com/lixiansheng/p/11348050.html