集合
一、集合接口及抽象类
1、java中集合类的基本接口是Colliction接口:
public interface Colliction<E>{
//接口中最常用的两个基本方法
boolean add (E element); //向集合中添加元素
Iterator <E> iterrator(); //迭代器
..........
}
1)迭代器:迭代器方法是Colliction 接口中一个重要的方法,它将返回一个实现了 Iterator 接口的对象。
作用:依次对集合中的元素进行访问
Iterator 接口:
public interface Iterator<E> extends Iterable<E>{
E next(); //访问集合中的元素,反复调用会遍历整个集合,到达末尾抛出一个异常
boolean hasNext(); //检测是否还有元素供next()方法访问,如果有返回true 可放在next方法之前做检测
void remove(); //删除集合中的元素
}
迭代器是一个重要的集合元素的工具,为了方便理解,可以将next()想象成一个游标,将集合想象成一个元素
一字排列的轨道,新定义的迭代器next()指向轨道开始,游标每次只能向后滑动一个元素然后停留在两个元素中间,游标
滑动后可以对被越过的元素进行操作。当然,hasNext()就是检测游标是否到轨道尽头。
2)删除元素
可以在next()方法后调用 remove() 方法删除元素,但是调用一次 next() 只能调用一次 remove() ;
3)在Collection 接口中,有很多比较实用的泛型泛型方法供用户使用。
2、扩展了Collection 接口的抽象类 AbstractCollection
这个类扩展了Collection接口,提供可例行方法,用户可以扩展此类,而不需要实现接口中所有的方法,
减轻用户的负担。
二、集合的分类
集合可分为:List 、 Set 、 Map 三大类
List :元素可以重复,有序
Set:元素不可以重复,无序
Map:存放键值对,无序,键不可以重复
注:这里所说的“无序”与“有序”代表的是存放元素的内存地址的限定,并不是按照某种规则给元素排序。
1、List
包括 ArrayList 和 LinkList
1) LinkList 链表(都是双向的)
和数据结构中的链表基本特性是一样的
在链表中,集合类库提供了ListIterator <E> extends Iterator<E> 接口,在其中扩充了一些实用的方法。
与next()方法一样 ListIterator 接口中还定义了一个 E previous() 和 boolean hasPrevious() 方法,用于反向遍历链表。
可以用ListIterator 对象对链表中的元素进行增、删、改,这就实现了链表的基本功能。
在对拉表中的元素操作的时候,都依赖于迭代器,必须用next访问到这个元素。
注:在链表中,定义多个迭代器的时候可能会出现并发异常。由于一有的迭代器对链表进行了更改,其他迭代器无法同步。
如果迭代器发现,集合被其他迭代器或集合本身的方法修改,将会抛出一个异常
这里所说的修改针对的是增、删。改变某个元素的值并不影响。
增删对于链表来说是高效的,但是查找对于链表来说并不是很高效,所以尽量避免应具体的索引值对链表进行查找。
2)ArrayList 数组列表
ArrayList 封装了一个动态再分配的对象数组,对查找高效,但是增删不高效。
ArrayList 与 Vector的区别在于:Vector 同步 ArrayList 不同步
2、Set
1)散列集
简介:散列集就是根据对象的散列码,将元素存放在散列表中。
散列表:用一个链表数组表示,每个链表抽象为一个桶,桶里可以装多个不相同的元素。
存储方式:首先计算出散列码,用散列码与桶数取余,得到的数就是要存放的桶的编号,然后遍历桶中的元素
如果没有与之相同的,就将这个元素存入桶中。
再散列:装填因子0.75(默认值),当75%的桶都装填了元素,那么将桶的数增加到双倍,然后再散列。默认16个桶。
类库提供了一个HashSet类,实现了基于散列表的集。
例:Set<String> A = new HashSet<>();
2)树集(红黑树)TreeSet
简介:树集对散列集进行了改进,随机的存入元素,但是元素会按约定的顺序进行排序,遍历的时候就是有序的。
与散列集对比:比将元素添加到散列集中慢。
要求:存入树集中的对象必须扩展了Comparable 接口
Comparable 接口的局限性:一个类只能实现一次该接口,但是要对对象进行不同类型的排序的时候就会出现问题。
解决方法:可以将Comparator 对象传递给TreeSet构造器,告诉树集使用不同的比较方法
public interface Comparator<T>{
int compare(T a ,T b); //与compareto方法类似
}
//使用方法
SortedSet<Item> sortByDescription = new TreeSet<>(new Comparator<Item>(){........});
//SortedSet extends Set TreeSet implements SortedSet
注:在合适的时候选择TreeSet
TreeSet 实现了NavigableSet接口,新增了便于定位元素及反向遍历的方法。
3、Map
对键的一种操作
分类:HashMap 、TreeMap
例: Map <String , Employee> staff = new HashMap<>();
注:与前面几种集合不同,Map中添加元素用put();当存入相同键时put()方法会将原先的值返回。
集合框架没有将映射表本身视为一个集合(其他的数据结构框架除外),但是可以获得映射表的视图,
实现了Collection接口对象,或者它的子接口的视图。
三个视图:键集、值集合、键/值对集
Set<K> keySet(); //失信了Set接口的某个其他类对象。
Collection<K> values();
Set<Map.Entry<k,v>> entrySet();
不可以对视图进行添加,如果删除键集中的元素,就从映射表中删除了整个元素。
专用集与映射表类
1)若散列映射表:WeakHashMap使用弱引用保存键。WeakReference 将对象引用保存在单列表键中,如果一个对象只能被WeakHshMap引用,那么他将被垃圾回收器收回,将弱引用放在队列中,WeakHashMap检查队列,删除新添加进来的键对应的条目。通俗说:就是删除散列表中不再使用的条目
2)链接散列表和链接映射表。
LinkedHashSet 与 LinkedHashMap
将散列的元素组织成一个链表
特性:访问一次链表结构变一次,被访问的元素被放到链表末尾。
LinkedHashMap<k,v> (initialCapacity,loadFactor,true){...........}
3)枚举集与映射集
EnumSet 和 EnumMap
enum A{A,B,C};
EnumMap<E> always = new EnumMap<>(a.class); 必须指定键的类型
4)标识散列映射集 ,散列码使用内存地址进行计算的。
三、几种特殊的集合
1、队列与双端队列,实现了Deque接口,ArrayDeque与LinkedList。
特性:可在队头或队尾同时添加或者删除元素。
2、优先级队列, 相当于数据结构中的小顶堆。PriorityQueue<E>。
特性:可以优先删除最小的元素。