集合-有时也称为容器-组合多个元素到单一单元。
用于store,retrieve,manipulate,communicate aggregate data。
如:一手扑克牌(单张扑克牌集合),一个邮件文件夹(一组信件),一个电话本(映射名字到电话号码)。
集合框架是一个一致的架构用于表示且操做集合。包含以下:
接口:这些都是表示集合的抽象数据类型。接口容许集合独立操做的细节表示。在OO语言中,接口一般造成一个层次结构。
实现:这些都是集合接口的具体实现,从本质上说,它们是可重用的数据结构。
算法:这些方法执行有用的计算。好比搜索和排序,在一个实现集合接口的对象。从本质上说,它们是可重用功能。
java 集合框架的特性:
减小编程工做
提升程序开发的速度和质量
容许不相关的api之间的互操做
减小努力学习和使用新的api
减小努力设计新的api
培养软件重用
为了保持核心集合接口数量可管理,java没有为每种集合类型的变体提供分离的接口(如变体可能包含不可变,固定大小和只追加),代替,在每一个集合接口中的修改操做设计成可选,
给定一个实现可能选择不支持全部的操做,若是一个不支持的操做被调用,集合抛出UnsupportedOperationException,实现负责记录的可选的业务支持,全部的Java平台的通用实现都支持全部可选操做。java
Collection Interface
Collection 表示一组对象,这些对象也称为 collection 的元素。此接口一般用来传递 collection,并在须要最大广泛性的地方操做这些 collection。
一般,全部通用Collection的实现有一个带Collection参数的构造器,这个构造器被称为一个转换构造器,初始化一个新的Collection去包含指定Collection的全部元素,
不管给定集合的子接口或实现类型。换言之,它容许你转换集合的类型。
遍历集合
一、使用聚合操做;二、使用for-each语句;三、使用Iterators
Iterator是你能够遍历一个collection而且有选择的从集合中移除元素。
若是迭代中有更多的元素,hasNext方法返回true,next方法返回迭代中的下一个元素。
remove方法移除经过next方法返回最后一个元素。remove方法只有每次调用next方法后被调用,如违反这个规则则抛出异常。
注意,Iterator.remove是仅有安全方式修改一个Collection在迭代时,若是底层迭代以任何其余方式而集合被修改则行为是未指定的。
有时你须要使用Iterator代替for-each语句:
移除当前元素。for-each语句隐藏了迭代器,所以你不能调用remove。因此for-each语句不适应于过滤。
并行的遍历多个Collections
下面方式说明如何使用Iterator过滤一个任意Collection,遍历该集合移除指定元素:
static void filter(Collection<?> c) {
for (Iterator<?> it = c.iterator(); it.hasNext(); )
if (!cond(it.next()))
it.remove();
}
强大批量操做的例子,考虑从一个Collection,c中移除全部指定元素e的实例:
c.removeAll(Collections.singleton(e));
更具体的说,假如你想要移除一个Collection中全部null元素:
c.removeAll(Collections.singleton(null));
Collections.singleton是一个静态工厂方法,返回一个仅包含指定元素不可变的Set。
Set Interface
不能包含重复元素的Collection。它是数学模型Set的抽象。该接口仅包含继承Collection的方法且添加禁止重复元素的限制。
Set在equals和hashCode操做行为上添加更强的约定,容许Set的实例能够比较的即便它们的实现不一样。若是2个Set实例包含相同的元素,则2个实例是相等的。
java提供3种Set的实现:HashSet、TreeSet和LinkedHashSet。HashSet在一个hash table中存储它的元素,也是表现最好的实现;可是它不保证有关的顺序迭代。
TreeSet在一个red-black tree中存储它的元素,元素的顺序是基于它们的值,比HashSet慢得多。
LinkedHashSet用链表进行优化设计hash table的实现,元素的顺序是基于元素插入的顺序。
假如你有Collection,c,而且你想要建立另外一个Collection包含相同元素但排除重复元素,如:
Collection<Type> noDups = new HashSet<Type>(c);
Collection<Type> noDups = new LinkedHashSet<Type>(c);//保留原始元素的顺序
算法
List Interface
是一个排序的集合(有时也称为序列)。Lists中能够包含重复元素,除了继承Collection操做外,List接口包含以下操做:
位置访问:操做元素是基于数值的位置,如get,set,add,addAll,和remove
搜索:在列表中搜索指定的对象,并返回其数值的位置,如indexOf,lastIndexOf
迭代:继承Iterator语义提供list顺序的迭代,如listIterator
查看范围:sublist方法执行任意范围的操做
remove方法老是从list中移除第一个出现的指定元素;add/addAll老是添加新元素到list的末尾。
同Set同样,List在equals和hashCode操做行为上添加更强的约定,容许Set的实例能够比较的即便它们的实现不一样。若是2个Set实例包含相同的元素,则2个实例是相等的。
位置访问和搜索操做
基本的位置访问操做包括get,set,add,addAll,和remove(set和remove操做返回将被覆盖or移除的旧值),indexOf和lastIndexOf返回list中第一个or最后一个指定元素。
addAll从指定位置开始插入指定Collection中全部的元素。元素插入的顺序则是经过Collection的迭代返回的顺序。
Iterators
经过list的iterator方法返回适当顺序的list的元素。list提供更强大的iterator,称为(ListIterator)。你能够在任何一个方向遍历列表,遍历中修改列表,并得到迭代器的当前位置。 ListIterator从Iterator继承hasNext,next,remove。hasPrevious,previous相似于hasNext,next。前面的的操做引用隐式光标以前的元素,然后面的则引用光标以后的元素。previous向后移动光标,next向前移动光标。更直接的说,光标老是位于2个元素之间(一个调用previous将返回的元素和一个调用next将返回的元素)。N + 1的有效索引值对应于元素之间N + 1个间隙,从第一个元素前面的间隙到最后一个元素的间隙。编程
调用next和previous能引发混乱,须要当心使用。api
nextIndex 方法返回随后调用next返回元素的索引号,previousIndex方法返回随后调用previous返回元素的索引号。这些调用一般用来报告某些元素被查找的位置or记录ListIterator的位置以即可以使用相同的位置建立另外一个ListIterator
nextIndex返回的值老是大于previousIndex返回的值,这意味着2种边界行为:
(1)、当光标位于初始元素以前,调用previousIndex返回-1
(2)、当光标位于最后元素以后,调用nextIndex返回list.size()
以下一种可能实现List.indexOf:
public int indexOf(E e) {
for(ListIterator<E> it = listIterator (); it.hasNext();)
if(e == null ? It.next == null : e.equals(it.next())
return it. previousIndex();//返回向前检查过的元素的索引
return -1;
}
iterator接口提供remove方法用于从Collection中移除由next返回最后元素。 ListIterator的操做移除由next/previous返回最后元素,ListIterator还提供2个额外的操做来修改list(set/add),set方法使用指定元素覆盖由next/previous返回最后元素。如:
public static <E> void replace(List<E> list, E val, E newVal) {
if(val == null ? It.next == null : val.equals(it.next())
it.set(newVal);
}
add方法在当前光标以前插入一个新的元素。如:
public static <E> void replace(List<E> list, E val,
List<? extends E> newVals) {
if(val == null ? It.next == null : val.equals(it.next())
it.remove();
for(E e: newVals)
it.add(e);
} 安全
rang-view
subList(int fromIndex, int toIndex)返回list试图,从formIndex(包括)到toIndex(不包括)的范围list的分区
返回的list是经过在subList调用时由List备份的,全部前者的改变会影响到后者。
一般能够再一个range中查找一个元素,如:
int i = list.subList(fromIndex, toIndex).indexOf(obj);
int j = list.subList(fromIndex, toIndex).lastIndexOf(obj);
注意,在subList视图中查找指定元素的索引号,而不是后面的List
数据结构