前段时间老师让看看java的基础,查了网上的一些资料加上自己的总结做了个word文档交给老师。当然问题很多,老师建议自己开个博客把所学的东西放到上面并定时更新,而且如果有人看到的话也可以提出好的意见有利于学习。想想也对,于是就厚着脸皮把东西贴上来了,希望能够作为自己学习的一个记录,如果大家有好的意见可以随时提出,让我能够更好的学习。先谢谢大家了。
一、数组类Array
Java中最基本的一个存储结构,用于存放一组连续的基本类型或对象数据,其中的元素类型必须相同。在所有集合类中,数组的效率是最高的,但是也存在着两个问题:(1)容量固定无法动态改变,当要保存的容量无法确定时通常采用预先分配一个很大的空间来避免出现空间不足的情况,这样会导致资源的浪费。而且无法判断数组中世纪存放了多少元素,length属性只是告诉我们数组的容量而不是实际存放的元素个数。
二、Java集合框架的成员
主要包括Collection和Map两种类型和相应的接口。List和Set继承了Collection接口;Vector、ArrayList和LinkedList三个类实现了List接口;HashSet、TreeSet实现了Set接口;HashTable、HashMap和TreeMap实现Map接口。List、Set和Map的特征分别为:List区分元素的顺序,允许包含值相同的元素;Set不区分元素的顺序,因此不允许包含相同的元素;Map保存“键”—“值”对,即”key”—“value”,其中,键值不能重复,而且一个键key只能对应一个值。
常用集合类的继承结构:
Collection<--List<--Vector
Collection<--List<--ArrayList
Collection<--List<--LinkedList
Collection<--Set<--HashSet
Collection<--Set<--HashSet<--LinkedHashSet
Collection<--Set<--SortedSet<--TreeSet
Map<--SortedMap<--TreeMap
Map<--HashMap
详细描述如下:
List,是有序的元素集合,它的组成元素可以是单个相同或不同类型的对象;List中允许存在着相同的元素,例如一个ArrayList<Integer> alist中可以包含两个整数1,这两个1处于alist中的不同位置;List中可以有空元素,测试如下:
List list=new ArrayList();
list.add(null);
System.out.println(list.size()+""+list.get(0));
输出的结果为1 null,表明list中存在着一个null值的元素。
2.1 List派生出的集合类包括ArrayList,Vector和LinkedList三种。
(1)Vector可以看作是基于数组的List,封装了数组所不具备的一些功能以方便使用。这也导致Vector无法避免数组的限制,性能也要逊于直接使用数组。值得注意的一点在于,Vector的方法中采用了synchronized进行同步,因此Vector是线程安全的,不过同步也导致了效率的降低。
(2)ArrayList与Vector类似,是一个基于数组的列表,但是ArrayList没有考虑同步问题,所以在性能上比Vector好;在涉及到多线程的环境时,需要编程人员另外添加必要的同步管理。
ArrayList与Vector由于是基于数组的,因此适合查询,但是在插入和删除元素时需要移动大量元素,因此不适合在经常需要插入和删除元素的情况下使用。
(3)与Vector和ArrayList不同,不是基于数组的。它的概念与数据结构中的链表一致,其中的每个元素可以视为一个节点Node,包含两方面的信息:(1)节点本身的数据/值;(2)下一个节点的信息(nextNode),适用于数据经常发生添加和删除操作的时候,无需像基于数组的Vector和ArrayList那样需要移动大量的数据,而只需要改变nextNode的相关信息即可。
小结:在多数情况下,ArrayList的性能是最好的,但集合内的元素需要频繁的插入或删除时LinkedList表现较好,但是都比数组要差,因此在能用数组的情况下(元素类型和数组长度固定),应该尽量使用数组;否则,当操作以查询为主而且无需考虑多线程问题时,优先选用ArrayList;插入删除较为频繁时使用LinkedList。
2.2、Set
虽然Set与List都实现了Collection接口,但实现方式存在很大差异,Set是在Map的基础上实现的,相当于把Map中的Key作为Set的对应存储项,key是不能有重复的,因此Set不允许有重复的元素。如果使用add(Object obj)方法添加已经存在的对象,则会覆盖前面的对象。
2.2.1 HashSet
基于HashMap,这一点可以在源代码中的构造函数部分看出。
2.2 .2LinkedHashSet
是HashSet的一个子类,一个链表实现。
2.2.3 TreeSet
是SortedSet的子类,与HashSet的区别在于:TreeSet中的元素是有序的,通过接口SortedMap中提供的方法实现的。
2.3、Map
Map这种集合(容器)把键对象和值对象进行关联,其中一个值对象本身也可以是一个Map,用这种方式能够形成一个多级映射。为了保持查找结果的一致性,Map中的键对象不允许重复,否则将会导致混乱。在使用的过程中,添加对象等操作可能使某个键所对应的值对象发生变化,这时按照最后一次修改后得到的值与键相对应。键和值之间是一个多对一的映射,即多个键可以指向一个值;而一个键不能同时指向多个值。
Map的两种比较常用的实现是HashMap和TreeMap
2.3.1 HashMap采用了哈希算法,能够快速查找一个键
2.3.2 TreeMap对键进行有序存放,同时提供了firstKey(),lastKey()等一些扩展的方法。在使用中还可以从TreeMap中指定一个范围来取得它的子Map。
2.3.3 Hashtable:不允许空(null)键(key)或值(value),Hashtable的方法是Synchronize的,当多个线程访问Hashtable时,无需自己为它的方法实现同步,而HashMap就必须手动为止提供外同步。在性能上,Hashtable和HashMap采用的hash算法基本相同。
HashMap相当于Hashtable的轻量级实现(非线程安全的实现,类似于StringBuilder和StringBuffer之间的关系),二者都实现了Map接口,主要区别在于HashMap允许空(null)键(key)或值(value),非同步,由于非线程安全,效率上高于Hashtable。
三、Arrays
Arrays是java.util包中的一个类,提供了一组可用于数组的静态方法,这些方法都是一些实用的工具,其中最基本的五个方法是:
(1) equals(arr1,arr2):用来比较两个数组是否相等
(2) fill(arr,value):用于填充数组,但是只能用一个值,无法把随机生成的数字填进数组。
(3) sort(arr):对数组进行排序
(4) binarySearch(arr):在一个已排序的数组中查找元素的方法,二分查询。
(5) asList(arr):把一个数组转换成一个List容器。
四、Collections
Collections是一个工具类,提供一些静态方法来对集合类(List)进行基本操作。
(1) Collections.sort(List<T>list):根据元素的自然顺序对指定List集合的元素按照升序排列
(2) sort(List<T> list,Comparator<? super T> c):自然排序,Comparator接口定义了一个compareTo(Object obj)方法来比较元素之间的大小关系,然后将集合的元素按升序进行排序。
(3) binarySearch(List<? extendsComparable<? super T>> list, T key),对排好序的List进行二分搜索。
五、Iterator(迭代器)
迭代器是java.util中的一个类,也是一种设计模式,提供了一种方法来访问一个容器(container)对象中的各个元素而又不需要暴露该对象的内部细节。
可见,迭代器是为容器而生的,对容器对象的访问肯定涉及到遍历算法,(1)如果将便利方法塞到容器对象中,容器承受了过多的功能,既要维护内部元素,还要提供遍历自身的接口;而且由于遍历状态保存的问题,不能对同一个容器对象同时进行多个遍历;(2)让使用容器的人自己实现遍历,这种方法会暴露容器的内部细节。
如果操作的容器类支持,使用迭代器的好处在于:
1、 支持以不同的方式遍历一个容器角色
2、 能够简化容器的接口。虽然Collection中为了提高可扩展性仍然提供了遍历的接口。
3、 对同一个容器对象,可以同时进行多个遍历,因为遍历状态时保存在每一个迭代器对象中的。
迭代器模式适用于:
(1) 访问一个容器对象的内容,无需暴露它的内部表示
(2) 支持对容器对象的多种遍历
(3) 为遍历不同的容器结构提供一个统一的接口。
六、Enumeration接口
定义了从一个数据结构得到连续数据的手段,提供了一套标准的方法。由于Enumeration是一个接口,它的角色局限于为数据结构提供方法协议。
集合类之间的关系如下图所示: