Java大同之类集框架
Java的类集框架可以使程序处理对象的方法标准化,使用迭代方法访问类集可以使对类集的操作效率更加高。被设计成类集框架的拥有以下几种特性: 1、这种框架是高性能的。 2、框架必须允许不同类型的类集以相同的方式和高度互操作的方式工作。 3、类集必须是容易扩展和修改的。 Java API中所用的集合类,都是实现了Collection接口,也就是说框架的顶层是Collection,他的继承结构如下: Collection<--List<--Vector Collection<--List<--ArrayList Collection<--List<--LinkedList Collection<--Set<--HashSet Collection<--Set<--HashSet<--LinkedHashSet Collection<--Set<--SortedSet<--TreeSet Collection的常见方法: 1 删除 boolean remove(Object object) boolean removeAll(Collection coll) void clear(); 2添加 boolean add(Object object) boolean addAll(Collection coll) 3、判断: boolean contains(Object object) boolean containsAll(Collection coll) boolean isEmpty();//判断集合中是否有元素 4 获取 int size(); iterator();取出元素的方式;迭代器。 5其他: boolean retainAll(Collection coll )取交集 Object[]toArray() 将集合转成数组。 Vector : 基于Array的List,其实就是封装了Array所不具备的一些功能方便我们使用,它不可能不受Array的限制。性能也就不可能超越Array。所以,在可能的情况下,我们要多运用Array。另外很重要的一点就是Vector:同步的,这个也是Vector和ArrayList的唯一的区别。 ArrayList:同Vector一样是一个基于Array上的链表,但是不同的是ArrayList不是同步的。所以在性能上要比Vector优越一些,但是当运行到多线程环境中时,可需要自己在管理线程的同步问题。 LinkedList:LinkedList不同于前面两种List,它不是基于Array的,所以不受Array性能的限制。它每一个节点(Node)都包含两方面的内容:1.节点本身的数据(data);2.下一个节点的信息(nextNode)。所以当对LinkedList做添加,删除动作的时候就不用像基于Array的List一样,必须进行大量的数据移动。只要更改nextNode的相关信息就可以实现了。这就是LinkedList的优势。 List总结: 1. 所有的List中只能容纳单个不同类型的对象组成的表,而不是Key-Value键值对。例如:[ tom,1,c ]; 2. 所有的List中可以有相同的元素,例如Vector中可以有 [ tom,koo,too,koo ]; 3. 所有的List中可以有null元素,例如[ tom,null,1 ]; 4. 基于Array的List(Vector,ArrayList)适合查询,而LinkedList(链表)适合添加,删除操作。 5、List 特有的常见的方法:有一个共同特点就是都可以操作角标。1,添加void add(index,element)void add(index,collection) 2 删除 Object remove(index) 3 修改: object set(index,element) 4:获取object get(index);int indextOf(object);int lastIndexOf(object)List subList(from ,to); HashSet:虽然Set同List都实现了Collection接口,但是他们的实现方式却大不一样。List基本上都是以Array为基础。但是Set则是在HashMap的基础上来实现的,这个就是Set和List的根本区别。HashSet的存储方式是把HashMap中的Key作为Set的对应存储项。看看HashSet的add(Object obj)方法的实现就可以一目了然了。public boolean add(Object obj){return map.put(obj, PRESENT) == null;} 这个也是为什么在Set中不能像在List中一样有重复的项的根本原因,因为HashMap的key是不能有重复的。 LinkedHashSet:HashSet的一个子类,一个链表。 TreeSet:SortedSet的子类,它不同于HashSet的根本就是TreeSet是有序的。它是通过SortedMap来实现的。 Set总结: 1. Set实现的基础是Map(HashMap); 2. Set中的元素是不能重复的,如果使用add(Object obj)方法添加已经存在的对象,则会覆盖前面的对象 为什么要使用集合类 ? 当你事先不知道要存放数据的个数,或者你需要一种比数组下标存取机制更灵活的方法时,你就需要用到集合类。 理解集合类 集合类存放于java.util包中。 集合类存放的都是对象的引用,而非对象本身,出于表达上的便利,我们称集合中的对象就是指集合中对象的引用(reference)。 集合类型主要有3种:set(集)、list(列表)和map(映射)。 (1)集 集(set)是最简单的一种集合,它的对象不按特定方式排序,只是简单的把对象加入集合中,就像往口袋里放东西。 对集中成员的访问和操作是通过集中对象的引用进行的,所以集中不能有重复对象。 集也有多种变体,可以实现排序等功能,如TreeSet,它把对象添加到集中的操作将变为按照某种比较规则将其插入到有序的对象序列中。它实现的是SortedSet接口,也就是加入了对象比较的方法。通过对集中的对象迭代,我们可以得到一个升序的对象集合。 (2)列表 列表的主要特征是其对象以线性方式存储,没有特定顺序,只有一个开头和一个结尾,当然,它与根本没有顺序的集是不同的。列表在数据结构中分别表现为:数组和向量、链表、堆栈、队列。 关于实现列表的集合类,是我们日常工作中经常用到的,将在后边的笔记详细介绍。 (3)映射 映射与集或列表有明显区别,映射中每个项都是成对的。映射中存储的每个对象都有一个相关的关键字(Key)对象,关键字决定了对象在映射中的存储位置,检索对象时必须提供相应的关键字,就像在字典中查单词一样。关键字应该是唯一的。关键字本身并不能决定对象的存储位置,它需要对过一种散列(hashing)技术来处理,产生一个被称作散列码(hash code)的整数值, 散列码通常用作一个偏置量,该偏置量是相对于分配给映射的内存区域起始位置的,由此确定关键字/对象对的存储位置。理想情况下,散列处理应该产生给定范围内均匀分布的值,而且每个关键字应得到不同的散列码。 集合类简介 java.util中共有13个类可用于管理集合对象,它们支持集、列表或映射等集合,以下是这些类的简单介绍 集: HashSet: 使用HashMap的一个集的实现。虽然集定义成无序,但必须存在某种方法能相当高效地找到一个对象。使用一个HashMap对象实现集的存储和检索操作是在固定时间内实现的. TreeSet: 在集中以升序对对象排序的集的实现。这意味着从一个TreeSet对象获得第一个迭代器将按升序提供对象。TreeSet类使用了一个TreeMap. 列表: Vector: 实现一个类似数组一样的表,自动增加容量来容纳你所需的元素。使用下标存储和检索对象就象在一个标准的数组中一样。你也可以用一个迭代器从一个Vector中检索对象。Vector是唯一的同步容器类!!当两个或多个线程同时访问时也是性能良好的。 Stsck: 这个类从Vector派生而来,并且增加了方法实现栈!一种后进先出的存储结构。 LinkedList: 实现一个链表。由这个类定义的链表也可以像栈或队列一样被使用。 ArrayList: 实现一个数组,它的规模可变并且能像链表一样被访问。它提供的功能类似Vector类但不同步映射: HashTable: 实现一个映象,所有的键必须非空。为了能高效的工作,定义键的类必须实现hashcode()方法和equal()方法。这个类是前面java实现的一个继承,并且通常能在实现映象的其他类中更好的使用。 HashMap: 实现一个映象,允许存储空对象,而且允许键是空(由于键必须是唯一的,当然只能有一个)。 WeakHashMap: 实现这样一个映象:通常如果一个键对一个对象而言不再被引用,键/对象对将被舍弃。这与HashMap形成对照,映象中的键维持键/对象对的生命周期,尽管使用映象的程序不再有对键的引用,并且因此不能检索对象。 TreeMap: 实现这样一个映象,对象是按键升序排列的。 Set和List都是由公共接口Collection扩展而来,所以它们都可以使用一个类型为Collection的变量来引用。这就意味着任何列表或集构成的集合都可以用这种方式引用,只有映射类除外(但也不是完全排除在外,因为可以从映射获得一个列表。)所以说,把一个列表或集传递给方法的标准途径是使用Collection类型的参数。 如何记住每一个容器的结构和所属体系呢? 我的总结: List包括: ArrayList LinkedList set包括: hashSet TreaSet 后缀名就是该集合所属的体系。 前缀名就是该集合的数据结构。 看到Array:就要想到数组,就要想到查询快,有角标 看到link:就要想到聊表,就要想到删除快,就要要想到add get remove + frist last的方法。 看到hash:就要想到哈希表,就要想到唯一性,就要想到元素需要覆盖hascode方法和equals方法。 看到tree:就要想到二叉树,就要想到排序,就要想到两个接口Comparable,comparator, 而且通常这些常用的集合容器都是不同步的。 比如Vector 还是ArrayList,哪一个更好,为什么? 要回答这个问题不能一概而论,有时候使用Vector比较好;有时是ArrayList,有时候这两个都不是最好的选择。你别指望能够获得一个简单肯定答案,因为这要看你用它们干什么。下面有4个要考虑的因素: (1)API (2)同步处理 (3)数据增长性 (4)使用模式 我们要理解,比如,LinkList集合类在增加或移除集合中任何位置的元素所花费的时间都是一样的—O(1),但它在索引一个元素的使用却比较慢-O(i),其中i是索引的位置.使用ArrayList也很容易,因为你可以简单的使用索引来代替创建iterator对象的操作。LinkList也会为每个插入的元素创建对象,所以你要明白它也会带来额外的开销。 我的总结:类集框架为我们提供了一个功能强大的设计方案,以完成编程过程中的面临的大多数任务。 不是一篇博客就能讲完的,需要在实际中慢慢领会。