首页 > 代码库 > 黑马程序员——JAVA学习笔记八(集合)
黑马程序员——JAVA学习笔记八(集合)
1, JAVA最初版本只为最常用的数据结构提供了很少的一组类:Vector、Stack、Hashtable、BitSet与Enumeration接口,从JAVA1.2版本开始推出了一组功能完善的的数据结构。
集合类的由来:
对象用于封装特有数据,对象多了需要存储,如果对象的个数不确定。
就使用集合容器进行存储。
集合特点:
1,用于存储对象的容器。
2,集合的长度是可变的。
3,集合中不可以存储基本数据类型值。
4,接口与实现相互分离。
集合框架是为表示和操作集合而规定的一种统一的标准的体系结构。任何集合框架都包含三大块内容:对外的接口、接口的实现和对集合运算的算法。
2, Java类中,集合类中的基本接口是Collection接口,继承了Itearble接口。
Collection的常见方法:
1,添加。
boolean add(Object obj):
boolean addAll(Collection coll):
2,删除。
boolean remove(object obj):
boolean removeAll(Collection coll);
void clear();
3,判断:
boolean contains(object obj):
boolean containsAll(Colllection coll);
boolean isEmpty():判断集合中是否有元素。
4,获取:
int size():
Iterator iterator():取出元素的方式:迭代器。
该对象必须依赖于具体容器,因为每一个容器的数据结构都不同。
所以该迭代器对象是在容器中进行内部实现的。
对于使用容器者而言,具体的实现不重要,只要通过容器获取到该实现的迭代器的对象即可,
也就是iterator方法。
Iterator接口就是对所有的Collection容器进行元素取出的公共接口。
其实就是抓娃娃游戏机中的夹子!
5,其他:
boolean retainAll(Collection coll);取交集。
Object[] toArray():将集合转成数组。
为了让实现collection更简单,java类库提供了一个类AbstractCollection,它将基础方法size和itreator抽象化了。实现者只需要继承该类就行。
3, 迭代器,Iterator接口包含了3个方法,
public interface Iterator<E>
{
E next();
boolean hasNext();
void remove();
}
通过反复调用next方法可以逐个访问每个元素,不能用数组索引,到达末尾抛出NoSuchElementException异常。因此应该先调用hasNext()方法确保还有元素可供访问。 JAVA5以后可以使用for each访问。
for each循环可以与任何实现了Itreable接口的对象一起工作。
public interface Itreable<E> {
Itreator <E> itreator();
}
Itreator接口的next和hasNext方法与Enumeration接口的nexElement和hasMoreElements方法一样,但是这个太累赘。
删除元素,Itreator接口的remove方法将会删除上次调用next方法时返回的元素。如果调用remove之前没有调用next将是不合法的,这样会抛出一个IllegalStateException。
4, JAVA中具体的集合
Arraylist 一种可以动态增长和缩减的索引序列
LinkedList 一种可以在任何位置进行高效地插入和删除操作的有序序列
ArrayDeque 一种用循环数组实现的双端队列
HashSet 一种没有重复元素的无序集合
TreeSet 一种有序集合
EnumSet 一种含枚举类型值的集合
LinkedList 一种记住元素插入顺序次序的集合
ProiorityQueue 一种允许高效删除最小元素的集合
HashMap 一种存储键/值关联的数据结构
TreeMap 一种键值有序的排列的映射表
EnumMap 一种键值属于枚举类型的映射表
LinkedHashMap 一种可以记住键/值项添加次序的映射表
WeakHashMap 一种其值无用武之地后可以被垃圾回收器回收的映射表
IdentityHashMap 一种用== 而不是equals比较键值的映射表
4, List接口
List是有序集合,在JAVA中所有的链表都是双向列表。
由于LinkedList.add方法将对象添加到链表的末尾,但是有时需要把元素添加到中间,所以这个任务交给了迭代器。因为只有自然有序的集合使用迭代器添加才有意义(set就没有自然顺序),所以普通的Itreator没有add方法。集合类提供了ListItreator,其中包含了add方法,previous() hasPrevious()。add方法在迭代器之前添加一个新对象。当迭代器越过最后一个元素时,添加新的元素将会变成表末尾。如下ABC有四个位置可以插入。
|ABC A|BC AB|C ABC|,,如果调用next,再调用remove方法将会删除迭代器左侧的元素,如果是previous,则会将右侧的元素删除掉。不能调用两次remove。set方法将会用一个新元素取代调用next或previous返回的上一个元素。
链表迭代器能偶检测不同步修改,迭代器发现的他的集合被另一个迭代器或者集合本身修改(添加元素,删除元素)时,就会抛出一个Concurrent ModificationException异常。所以应该遵循以下规则:可以根据需要给容器附加许多的迭代器,但是这些迭代器只能读取列表,另外,再单独附加一个技能度又能写的迭代器。
虽然LinkList提供了get.但是要遍历效率低下。
如果需要对列表进行随机访问,可用ArrayList,Vector(同步安全)。
队列:public interface Queue <E>{
}
JAVA 6引入了双端队列: public interface Deque<E> {
}
ArrayDeque和LinkedList都实现了Deque接口。
优先级队列:元素可以按照任意的顺序插入,却总是按照排序的顺序进行检索。优先级队列队列使用了优雅高效的数据结构,称为堆。堆是一个自我调整的二叉树,对树执行添加add和删除remove操作,可以让最小的元素移动到根,而不必花费时间对元素进行排序。使用优先级的典型实例是任务调度。
5, Set接口
链表和数组按照人们的意愿排列元素的次序,但是想要查看某个元素,需要遍历所有元素。有一种数据结构,可以快速的查找所需要的对象,这就是散列表(hashTable)。散列表为每个对象计算一个整数,称为散列码。散列码是由不同的数据域的对象产生不同的散列码。自己实现的hashcode要与equals相兼容。JAVA中散列表用链表数组实现,每个列表称为桶(bucket),有时候桶满了,叫做散列冲突,这时需要比较元素内容。
Set是没有重复元素的的元素集合。
1,判断的是两个元素的哈希值是否相同。
如果相同,在判断两个对象的内容是否相同。
2,判断哈希值相同,其实判断的是对象的hashCode的方法。判断内容相同,用的是equals方法。
在更改集合中的元素时要格外小心,如果元素的散列码发生了改变,元素在数据结构中的位置也会发生改变。
TreeSet类与散列集类似,但是它是一个有序集合,可以按任何顺序将元素排序。使用红黑树,查找复杂度 log2n.
判断元素唯一性的方式:就是根据比较方法的返回结果是否是0,是0,就是相同元素,不存。
TreeSet对元素进行排序的方式一:
让元素自身具备比较功能,元就需要实现Comparable接口。覆盖compareTo方法。
如果不要按照对象中具备的自然顺序进行排序。如果对象中不具备自然顺序。怎么办?
可以使用TreeSet集合第二种排序方式二:
让集合自身具备比较功能,定义一个类实现Comparator接口,覆盖compare方法。
将该类对象作为参数传递给TreeSet集合的构造函数。 它是比较方法的持有器,将这种对象叫做函数对象,函数对象通常定位匿名内部类。
从JAVA6,TreeSet实现了NavigableSet接口,增加了几个便于定位元素以及反响遍历的方法。
6, 映射表,映射表用来存放键值对,如果提供了键,就能找到对应的值。
JAVA类为映射库提供了两个通用的实现:HashMap和TreeMap
散列映射表对键进行散列,树映射表用键的整体顺序对元素进行排序,并将其组织成搜索树。散列或比较函数只能作用于键,与键关联的的值不能进行散列或比较。键必须是唯一的,不能一个键对应两个值。
Map有三个视图,分别是 键集、值集合、键/值对集。
Set<K> keySet()
Collection<K> values()
Set<Map.Entry<K,V>>entrySet()
7, 集合框架,java的集合类构成了集合类的框架。它为集合的实现者定义了大量的接口和抽象类。
RandomAccess没有任何方法,可以用来检测集合是否支持高效随机访问。 ArrayList和Vector都支持该接口。
8, 视图与包装器,通过使用视图可以获得其他的实现了集合接口和映射表接口的对象,例如:keyset,初看起来,好像这个方法创建了一个新的
集合,并将所有的键值都填进去了,然后返回这个集合。然而这个情况并非如此。keyset方法返回了一个实现Set接口的的类对象,这个类的方法对原映射表进行操作,这种集合称为视图。视图技术在集合框架后中有许多非常有用的应用。
1,轻量级包装器,Arrays.aiList()将返回一个包装了普通JAVA数组的List包装器。不是ArrayList,它是一个视图对象,带有访问底层数组的get和set方法。还有Collections类包含了很多使用方法,这些方法的参数和返回值都是集合。
2,子范围,可以为很多集合建立子范围视图。例如。Collection.subrange(n1, n2)。可以将任何操作应用于子范围。
3,不可修改的视图,Collections还有几个方法,用于产生集合的不可修改视图(unmodifable views)。这些视图对现有集合增加了一个运行时的检查,如果发现试图对集合进行修改,则抛出一个异常。有6个:
Collections.unmodifiableCollection
****.unmodfiableList
****.unmodfiableSet
****.unmodfiableSortSet
****.unmodfiableMap
****.unmodfiableSortMap
4,同步视图,如果多个线程访问集合,就必须确保集合不被意外的破坏。如:Collections.synchornizedMap( Map)
5,检查视图,JAVA5增加了一组检查视图,用来对泛型类型发生的问题时提供调试支持。
ArrayList<Stirng > string = new ArrayList<>()
ArrayList st = string ;
str.add(new Date());
这个错误在运行时不会被检测出来。只有在强转时,才会抛出异常。
检查视图可以检测这一个问题。
Collection.checkList(string, String.class)
注:被检测视图受限于虚拟机可以运行的运行时检查。
9, 工具类Arrays Collections 数组与集合之间的转换。
List<T> Arrays.asList(T...) 数据转化为集合
Object[] toArray() 集合转化为数组
<T> T[] toArray(T[] a)集合转为为数组
返回包含此 collection 中所有元素的数组;返回数组的运行时类型与指定数组的运行时类型相同。如果指定的数组能容纳该 collection,则返回包含此 collection 元素的数组。否则,将分配一个具有指定数组的运行时类型和此 collection 大小的新数组。
如果指定的数组能容纳 collection,并有剩余空间(即数组的元素比 collection 的元素多),那么会将数组中紧接 collection 尾部的元素设置为 null。(只有 在调用者知道此 collection 没有包含任何 null 元素时才能用此方法确定 collection 的长度。)
如果此 collection 对其迭代器返回的元素顺序做出了某些保证,那么此方法必须以相同的顺序返回这些元素。
黑马程序员——JAVA学习笔记八(集合)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。