集合
队列接口
两个实现:
ArrayDeque 循环数组队列,高效但容量有限
LinkedList 链表队列
集合类的几本接口是Collection
链表
LinkedList 实现了List接口
如果希望添加到链表中间位置,使用子接口列表迭代器ListIterator,其中包含add方法:
例如
LinkedList 获取某个元素
LinkedList 提供了一个用来访问某个特定元素的get方法,staff.get(n); 每次都要从链表的头部重新开始搜索。
而列表迭代器实现了一个方法:
staff.listIterator(n)将返回一个迭代器,这个迭代器指向索引为n的元素前面的位置。
然后调用iter.next产生与staff.get(n)同一个元素。
数组
LinkedList实现了List接口,List有两种访问方式:
一种是使用迭代器,一种是使用get 和set方法随机访问某个元素。后者不适合链表。
Q1: ArrayList 和 Vector的区别?
散列表
快速查找所需要的对象
用链表数组实现
散列冲突: 相对应的桶被占满
装填因子(load factor):决定何时对散列表进行再散列,如75%,说明表中75%的位置已经填入元素,这个表会用双倍的桶数自动进行再散列。
HashSet: 实现了基于散列表的集合,implements Set
创建 HashSet(int initialCapacity, float loadFactor) 指定容量和装填因子(0.0~1.0之间的数值)的空散列集。
树集
TreeSet 有序集合
排序是用红黑树实现的
implements SortedSet()
Q2: 红黑树?算法导论里有提到
如果树中包含n个元素,查找新元素的正确位置平均需要logn (底为2)次比较,因此将一个元素添加到TreeSetz中要比添加到HashSet中慢。
队列与双端队列
|
|
优先级队列
使用堆(自我调整的二叉树)实现。
可以按人意顺序插入,却按排序的顺序检索,默认返回队列中最小的元素。
映射表
两个通用实现:HashMap 和 TreeMap。 实现了Map接口。
HashMap:
HashMap(int initialCapacity, float loadFactor) 指定容量和装填因子(0.0~1.0之间的数值)的空散列映射表。
TreeMap:
有序映射表
Q3: TreeMap的使用场景?
专用集和映射表类
WeakHashMap
LinkedHashSet和LinkedHashMap,用来记住插入元素项的顺序。
EnumSet是一个枚举类型元素集的高效实现。由于枚举类型只有有限个实例,所以EnumSet内部用位序列实现,如果对应的值在集中,则相应的位被置1。
EnumMap: 键类型位枚举类型的映射表。
Java 类库支持下面几种具体类
LinkeList
ArrayList
ArrayDeque
HashSet
TreeSet
PriorityQueue
HashMap
TreeMap
批操作
|
|
算法
终于到了算法的部分了!
排序
java 的排序将所有元素转入一个数组,并使用一种归并排序的变体对数组进行排序,然后,再将排序后的序列复制回列表。
集合中的归并排序比快排要慢一些,但是优点:稳定,即不需要交换相同的元素。
混排
随机混排列表中的元素:
复杂度分析:
sort的时间复杂度是O(nlogn),n为列表长度。
shuffle 时间复杂度是O(n a(n)), a(n) 是访问元素的平均时间。
Q4: 实现集合的shuffle算法?
二分查找
排好序的集合使用下面的二分查找,提供参数:集合和要查找的元素
如果返回数值大于等于0,则表示匹配对象的索引。
如果返回负值,则表示没有匹配的元素。但是可以利用返回值计算应该将element 插入到集合的哪个位置,以保持集合的有序性。插入的位置是
注:只有采用随机访问,二分查找才有意义。如果必须利用迭代方式一次次遍历链表的一半元素来找到中间位置的元素,二分查找就完全失去了优势。
因此,如果为binarySearch算法提供一个链表,它将自动的变为线性查找。
时间复杂度:O(a(n)logn), a(n) 是访问元素的平均时间。
简单算法
|
|
编写自己的方法,尽量使用接口
遗留的集合
- Hashtable(t小写) 与HashMap的作用一样,方法是同步的,对同步性没有要求的情况下,应该使用HashMap
- 枚举
Enumeration两个方法,hasMoreElements 和 nextElement 属性映射表
Properties1234getProperty(String key)getProperty(String key, String defaultValue)没找到返回默认值load(InputStream in) // 从InputStream加载属性映射表store(OutputStream out, String commentString) // 把属性映射表存储到OutputStream栈 Stack
push, pop, peek位集 Bitset
1234567get(i) // 第i位位于“开”状态,返回trueset(i) // 设置为“开”clear(i) // 设置为"关”andorxorandNot应用,找素数
找出100以内的素数
素数定义:质数,又称素数,指在一个大于1的自然数中,除了1和此整数自身外,无法被其他自然数整除的数(也可定义为只有1和本身两个因数的数)。
使用Java.util.BitSet求素数的算法:
例如要找100以内的素数,
1,声明一个BitSet bs,第0,1位置false;其余位是true。
2,从2开始遍历bs,如果是true就进行内循环遍历。
3,内循环遍历:从外向内环i开始遍历bs,每次增长一个i(这个很重要),把内循环j在bs中的位置成false。
代码如下
完整的代码