集合框架
java集合可以理解为一个容器,这个容器可以存储数量不等的多个对象
注:集合实际存储的是对象的引用,即内存地址值。
集合框架的构成及分类
![](https://img-my.csdn.net/uploads/201304/19/1366371050_6303.jpg)
Java集合的四种体系
List 代表有序,可重复的集合
Set 代表无序不可重复的集合
Map 代表具有映射关系的集合
Queue 代表一种队列集合实现
数组与集合的区别:
数组和集合都是容器,都可以存储数据。
数组长度是固定的,集合长度是可变的。
集合可以存储具有映射关系的数据,数组不可以。
数组元素既可以是基本类型的值,也可以是对象,
集合只能保存对象
Collection接口
Collection定义了集合框架的共性功能。
1,添加
boolean add(Object o); 将元素o添加到指定集合
boolean addAll(collection c); 将集合c里的一组或所有元素添加到指定集合
2,删除
bollean remove(Object o); 删除集合中第一个发现的指定元素o,
bollean removeAll(collection c); 删除一组元素,指定集合中会删除和集合c相同的元素(相当于删除交集)。
void clear(); 清除集合里所有元素,将长度变0
3,判断
bollean contains(Object o); 返回集合是否包含某个指定元素o
bollean containsAll(collection c); 返回集合是否包含集合c里某组或所有元素
bollean isEmpty(); 返回集合是否为空,集合长度为0时返回true,否则返回false。
4,获取
iterator iterator(); 获取迭代器,用于取出集合中的元素
int size(); 获取集合长度
5,获取交集。
boolean retainAll(collection c); 指定集合中只会保存和集合c相同的元素。
6,集合变数组。
Object[] toArray(); 将指定集合转换成一个数组,所有集合元素变成对应数组元素。
注:所有Collection集合实现类都重写了toString()方法,该方法可以一次性输出集合中的所有元素。
如果想要依次访问集合中每个元素,则需要使用某种方式遍历集合元素。
遍历集合元素的两种方式:
1 使用Iterator接口遍历集合元素
Iterator
作用:隐藏各类Collection实现类的底层细节,向程序提供遍历Collection集合元素的统一编程接口
使用Iterator的注意事项:
1 当使用Iterator对集合元素进行迭代操作时,Iterator并不是把集合元素本身传给迭代变量,而是把集合元素的值传给迭代变量,所以修改迭代变量的值对集合元素本身没有任何改变。
2 当使用Iterator来迭代访问Collection集合元素时,集合中的元素不会被改变,只有通过Iterator的remove方法来删除上一次next方法返回的集合元素才可以。否则将引发java.util.ConcurrentModificationException异常。
Iterator的三个方法:
bollean hasNext(); 判断集合中是否有元素可被迭代,如果有则进行遍历操作
Object next(); 返回集合中将要迭代的下一个元素
void remove(); 删除集合中上一次next方法返回的元素
2 使用foreach循环遍历集合元素
List接口
List代表一个有序集合,集合中每个元素都有其对应的顺序索引,该集合允许使用重复元素,可以通过索引来访问指定位置的集合元素。List集合默认按元素的添加顺序设置元素的索引。
List中常见的三个子集合:
ArrayList:
底层是数组数据结构。特点:查询速度很快,增删操作稍慢,线程不同步。
LinkedList:
底层使用链表数据结构。特点:增删操作很快,查询稍慢,线程不同步。
Vector:
底层是数组数据结构。因为具备安全性,所以效率低下,从5.0版本开始被ArrayList替代,线程同步。
Vector的特有取出方式是枚举(Enumeration),枚举和迭代器是一样的,因为枚举的名称和方法名都过长,所以被迭代器取代。
Enumeration接口的功能与Iterator 接口的功能是重复的。此外Iterator接口添加了一个可选的移除操作,并使用较短的方法名。新的实现应该优先考虑使用Iterator接口而不是Enumeration接口。
List集合的操作方法:
List做为Collection子接口,可以使用Collection接口全部方法。
因为List是有序集合,List集合里添加了一些根据索引来操作集合元素的方法:
1,增
void add(int index,Object element); 将元素element插入List集合的index处。
boolean addAll(int index,Collection c); 将集合c所包含的所有元素都插入List集合index处。
2,删
Object remove(int index); 删除并返回index索引处的元素。
3,改
Object set(int index,Object element); 将index索引处的元素替换成element对象,返回新元素。
4,查
Object get(index): 返回集合index索引处的元素。
List subList(int fromIndex,int toIndex); 返回从索引fromIndex(包含)到索引toIndex(不包含)处所有集合元素组成的子集合。
int indexOf(Object o): 返回对象o在List集合中第一次出现位置的索引。
int lastIndexOf(Object o): 返回对象o在List集合中最后一次出现位置的索引。
ListIterator listIterator(); 获取List集合的特有迭代器。
ListIterator
ListIterator是list集合特有的迭代器,在迭代时不可以通过集合对象的方法操作集合中的元素。因为会发生ConcurrentModificationException异常。
所以在迭代时,只能用迭代器的方法操作元素,可是Iterator方法是有限的,只能对元素进行判断、取出、删除操作,如果想要其他的操作如添加,修改等,就需要使用其子接口ListIterator。该接口只能通过List集合的listIterator方法获取。
ListIterator继承了Iterator,提供了专门操作List的方法。ListIterator在Iterator基础上增加如下方法:
boolean hasPrevious(): 返回该迭代器关联的集合是否还有上一个元素。
Object previous(): 返回该迭代器的上一个元素。
void add():在指定位置插入一个元素。
ListIterator与Iterator:
1,ListIterator增加了向前迭代的功能,Iterator只能向后迭代。
2,ListIterator可通过add方法向List集合中添加元素,Iterator只能删除元素。
LinkedList
底层使用链表数据结构。特点:增删操作很快,查询稍慢,线程不同步。
void addFirst(Obj o): 将指定元素插入指定集合的开头。
void addLast(Obj o): 将指定元素插入指定集合的末尾。
Object getFirst(): 获取,但不删除指定集合的第一个元素,如果集合中没有元素,则返回NoSuchElementException
Object getLast(): 获取,但不删除指定集合的最后一个元素。如果集合中没有元素,则返回NoSuchElementException
Object removeFirst(): 获取,并删除指定集合的第一个元素。如果集合中没有元素,则返回NoSuchElementException
Object removeLast(): 获取,并删除指定集合的最后一个元素。如果集合中没有元素,则返回NoSuchElementException
在JDK1.6出现了以下替代方法:
boolean offerFirst(Obj o): 将指定元素插入该集合的开头。
boolean offerLast(Obj o): 将指定元素插入该集合的末尾。
Object peekFirst(): 获取,但不删除该集合第一个元素,如果集合中没有元素,则返回null
Object peekLast(): 获取,但不删除该集合最后一个元素,如果集合中没有元素,则返回null
Object pollFirst(): 获取,并删除该集合第一个元素,如果集合中没有元素,则返回null
Object pollLast(): 获取,并删除该集合最后一个元素,如果集合中没有元素,则返回null
Set接口
实际上Set就是Collection,功能基本上完全一样,只是行为不同(Set不允许包含重复元素)。
HashSet
底层数据结构是哈希表,是线程不安全的,不同步。
HashSet保证元素唯一性的方法:
通过判断调用该元素的hashCode()方法的返回值是否相同并且调用该元素的equals()方法的返回值是否是true来完成。
如果元素的HashCode值相同,才会判断equals是否为true.
如果元素的HashCode值不相同,不会调用equals方法。
注:HashSet对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashCode和equals方法。
TreeSet
可以对Set集合中的元素进行排序。
底层数据结构是二叉树
保证元素唯一性的方法:compareTo方法return 0.
- TreeSet排序的第一种方式:
- 让元素自身具备比较性。
- 元素需要实现Comparable接口,覆盖compareTo方法。
- 这种方式也称为元素的自然排序,或者叫默认顺序。
- Interger和String对象就实现了Comparable接口,并覆盖了compareTo方法,所以Interger和String对象本身具备比较性。}
- TreeSet的第二种排序方式:
- 当元素自身不具备比较性或者具备的比较性不是所需要的,这时就需要让集合自身具备比较性。
- 在集合初始化时,就有了比较方式。
- 定义一个比较器(定义一个类,实现Comparator接口,覆盖compare方法。)
- 将比较器对象作为参数传递给TreeSet集合的构造函数。
注:排序时,如果主要条件相同,一定要判断一下次要条件。
当两种排序都存在时,以比较器为主。
Map集合
用于保存具有映射关系的数据,此集合里保存两组数据,key和value, key不允许重复。
Map接口中定义了如下常用方法:
添加
Object put(K key,V value):添加一个key-value对,如果当前Map中已有一个与该key相等的key-value对,则新的key-vlaue对会覆盖原来的key-value对。
void putAll(Map m):将指定Map中的key-value对复制到本Map中。
删除
void clear():删除该Map对象中所有key-value对。
Object remove(Object key):删除指定key所对应的key-value对,返回被删除key所关联的value,如果该key不存在,返回null.
判断
boolean containsValue(Object value):查询Map中是否包含指定value,如果包含则返回true.
boolean containsKey(Object key):查询该Map中是否包含指定key,如果包含则返回true。
boolean isEmpty():查询该Map是否为空,即不包含任何key-value对。
获取
Object get(Object key):返回指定key所对应的value,如果集合中不包含key,则返回null.
int size():返回该Map里的key-value对的个数。
Collection values():返回该Map里所有value组成的Collection.
Set entrySet():返回Map中所包含的key-value对所组成的Set集合,每个集合元素都是Map.Entry(Entry是Map的内部类)对象。
HashMap
线程不同步,可以使用null作为key和value,
Hashtable
线程同步,不可以使用null作为key和value,
Map.Entry
Map集合并未实现Iterable,所以不能对Map集合中的元素进行直接迭代操作,而必须通过entrySet()方法获取到Map中所包含的key-value对所组成的Set集合,对Set集合进行迭代操作。
代码示例:
Map集合并未实现Iterable,所以不能对Map集合中的元素进行直接迭代操作,而必须通过entrySet()方法获取到Map中所包含的key-value对所组成的Set集合,对Set集合进行迭代操作。
代码示例:
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("zhangsan", 22);
map.put("lisi", 22);
Set<Map.Entry<String, Integer>> entryset = map.entrySet();
for (Map.Entry<String, Integer> entry : entryset) {
System.out.println(entry.getKey() + ":" + entry.getValue());
}
在Jsp页面中对Set或Map集合进行迭代操作:
<c:forEach items="${map}" var="entry">
${entry.key}:${entry.value}
<c/:forEach>