Java集合

    xiaoxiao2025-11-28  6

    声明:本文章经过别人文章摘要整理而来,并非纯原创作品! 集合框架    对于对象集合,必须执行的操作主要以下三种:  添加新的对象  删除对象  查找对象 Collection(对象之间没有指定顺序,允许元素重复) 1)、List(有序、不唯一) 对象之间有指定顺序,允许元素重复,并引入位置下标 a、ArrayList (动态数组)   b、LinkedList(链表)   2)、Set(无序、唯一) 对象之间没有指定顺序,元素不能重复 a、HashSet(散列集合)  b、TreeSet(树集合) c、SortedSet 2、Map(键值对、映射) 接口用于保存关键字(Key)和数值(Value)的集合,集合中的每个对象加入时都是提供 数值 和关键字。Map接口既不继承Set也不继承Collection。 1)、HashMap 2)、TreeMap   List、Set、Map、共同的实现基础是Object数组
     List(ArrayList、LinkedList) List就是列表的意思,它是Collection 的一种,即继承了Collection接口,以定义一个允许重复项的有序集合。该接口不但能够对列表的一部分进行处理,还添加了面向位置的操作。List是按对象的进入顺序进行保存对象,而不做排序或编辑操作。 它除了拥有Collection接口的所有的方法外还拥有一些其他的方法。 List: 简述实现操作特征成员要求提供基于索引的对成员的随机访问ArrayList提供快速的基于索引的成员访问,对尾部成员的增加和删除支持较好 成员可为任意Object子类的对象LinkedList 对列表中任何位置的成员的增加和删除支持较好,但对基于索引的成员访问支持性能较差 成员可为任意Object子类的对象 在“集合框架”中有两种常规的List实现:ArrayList和LinkedList。使用两种List实现的哪一种取决于您特定的需要。如果要支持随机访问,而不必在除尾部的任何位置插入或除去元素,那么,ArrayList提供了可选的集合。但如果,您要频繁的从列表的中间位置添加和除去元素,而只要顺序的访问列表元素,那么,LinkedList实现更好。 Map HashMap LinkedHashMap TreeMap Map接口不是Collection接口的继承 。而是从自己的用于维护键-值关联的接口层次结构入手。按定义,该接口描述了从不重复的键到值的映射。 这里需要注意的是,TreeMap中是根据键(Key)进行排序的。而如果我们要使用TreeMap来进行正常的排序的话,Key 中存放的对象必须实现 Comparable  接口。 Map简述实现操作特征成员要求 保存键值对成员,基于键找值操作,使用compareTo或compare方法对键进行排序 HashMap 能满足用户对Map的通用需求 键成员可为任意Object子类的对象,但如果覆盖了equals方法,同时注意修改hashCode方法。 TreeMap 支持对键有序地遍历,使用时建议先用HashMap增加和删除成员,最后从HashMap生成TreeMap;附加实现了SortedMap接口,支持子Map等要求顺序的操作 键成员要求实现Comparable接口,或者使用Comparator构造TreeMap键成员一般为同一类型 LinkedHashMap 保留键的插入顺序,用equals 方法检查键和值的相等性 成员可为任意Object子类的对象,但如果覆盖了equals方法,同时注意修改hashCode方法。 对于Map部分的使用和实现,主要就是需要注意存放“键值对”中的对象的 equals() 方法和 hashCode() 方法的覆写。如果需要使用到排序的话,那么还需要实现 Comparable  接口中的compareTo()方法。我们需要注意Map中的“键”是不能重复的,而是否重复的判断,是通过调用“键”对象的equals()方法来决定的。而在HashMap中查找和存取“键值对”是同时使用hashCode()方法和equals()方法来决定的。 HashMap的存入顺序和输出顺序无关。而LinkedHashMap则保留了键值对的存入顺序。TreeMap则是对Map中的元素进行排序。在实际的使用中我们也经常这样做:使用HashMap或者LinkedHashMap来存放元素,当所有的元素都存放完成后,如果使用则是需要一个经过排序的Map的话,我们再使用TreeMap来重构原来的Map对象。这样做的好处是:因为HashMap和LinkedHashMap存储数据的速度比直接使用TreeMap 要快,存取效率要高。当完成了所有的元素的存放后,我们再对整个的Map中的元素进行排序。这样可以提高整个程序的运行的效率,缩短执行时间。 Set 概述: Java 中的Set和正好和数学上直观的集(set)的概念是相同的。Set最大的特性就是不允许在其中存放的元素是重复的。根据这个特点,我们就可以使用Set 这个接口来实现前面提到的关于商品种类的存储需求。Set 可以被用来过滤在其他集合中存放的元素,从而得到一个没有包含重复新的集合。 Set简述实现操作特征成员要求  成员不能重复HashSet 外部无序地遍历成员。 成员可为任意Object子类的对象,但如果覆盖了equals方法,同时注意修改hashCode方法。  TreeSet 外部有序地遍历成员;附加实现了SortedSet, 支持子集等要求顺序的操作 成员要求实现Comparable接口,或者使用Comparator构造TreeSet。成员一般为同一类型。  LinkedHashSet 外部按成员的插入顺序遍历成员 成员与HashSet成员类似  排序: Set sortedSet = new  TreeSet(set1); System.out.println("排序后 TreeSet :" + sortedSet ); HashSet的元素存放顺序和我们添加进去时候的顺序没有任何关系,而LinkedHashSet 则保持元素的添加顺序。TreeSet则是对我们的Set中的元素进行排序存放。 迭代器Iterator Collection接口的iterator()方法返回一个Iterator。Iterator和您可能已经熟悉的Enumeration接口类似。使用 Iterator接口方法,您可以从头至尾遍历集合,并安全的从底层Collection中除去元素。 ListIterator接口继承Iterator接口以支持添加或更改底层集合中的元素,还支持双向访问 以HashSet举例: Set set1 =  new  HashSet(); Iterator iterator =set1.iterator(); //得到一个迭代器         while  ( iterator.hasNext() ) { //遍历          Object element =iterator.next();            System.out.println("iterator = "  + element);         } 集合框架中常用类比较 用“集合框架”设计软件时,记住该框架四个基本接口的下列层次结构关系会有用处: Collection 接口是一组允许重复的对象。 Set 接口继承 Collection,但不允许重复。 List 接口继承 Collection,允许重复,并引入位置下标。 Map 接口既不继承 Set 也不继承 Collection,存取的是键值对 我们以下面这个图表来描述一下常用的集合的实现类之间的区别: 排序 Comparable 接口 compareTo()方法比较当前实例和作为参数传入的元素。如果排序过程中当前实例出现在参数前,就返回某个负值。如果当前实例出现在参数后,则返回正值。否则,返回零。这里不要求零返回值表示元素相等。零返回值只是表示两个对象排在同一个位置。 在 Java 2 SDK,版本 1.2 中有十四个类实现Comparable接口。下表展示了它们的自然排序。虽然一些类共享同一种自然排序,但只有相互可比的类才能排序。 创建您自己的类Comparable只是个实现compareTo()方法的问题。通常就是依赖几个数据成员的自然排序。 您自己的类也应该覆盖equals()和hashCode()以确保两个相等的对象返回同一个散列码 Comparator 接口 若一个类不能用于实现 java.lang.Comparable,您可以提供自己的 java.util.Comparator 行为。如果您不喜欢缺省的Comparable 行为,您照样可以提供自己的 Comparator。 Comparator 的 compare() 方法的返回值和 Comparable 的 compareTo() 方法的返回值相似。在此情况下,如果排序时第一个元素出现在第二个元素之前,则返回一个负值。如果第一个元素出现在后,那么返回一个正值。否则,返回零。与 Comparable 相似,零返回值不表示元素相等。一个零返回值只是表示两个对象排在同一位置。由Comparator 用户决定如何处理。如果两个不相等的元素比较的结果为零,您首先应该确信那就是您要的结果,然后记录行为。 为了演示,您会发现编写一个新的忽略大小写的 Comparator,代替使用 Collator 进行语言环境特定、忽略大小写的比较会更容易。这样的一种实现如下所示: classCaseInsensitiveComparator implements Comparator {   public int compare(Object element1, Objectelement2) {      String lowerE1 =((String)element1).toLowerCase();      String lowerE2 =((String)element2).toLowerCase();      return lowerE1.compareTo(lowerE2);    } } 因为每个类在某些地方都建立了 Object 子类,所以这不是您实现 equals() 方法的必要条件。实际上大多数情况下您不会去这样做。切记该 equals() 方法检查的是 Comparator 实现的等同性,不是处于比较状态下的对象。 Collections 类有个预定义的 Comparator 用于重用。调用 Collections.reverseOrder() 返回一个 Comparator,它对逆序实现 Comparable 接口的对象进行排序。 在JAVA的util包中有两个所有集合的父接口Collection和Map,它们的父子关系:             java.util         +Collection  这个接口extends自 --java.lang.Iterable接口             +List  接口                 -ArrayList                 -LinkedList                 -Vector  类     此类是实现同步的             +Queue  接口                + 不常用,在此不表.             +Set  接口                +SortedSet  接口                   -TreeSet                 -HashSet          +Map  接口            -HashMap  类 (除了不同步和允许使用null 键/值之外,与 Hashtable 大致相同.)            -Hashtable  类此类是实现同步的,不允许使用null 键值            +SortedMap  接口               -TreeMap            以下对众多接口和类的简单说明:首先不能不先说一下数组(Array) 一、Array , Arrays Java所有“存储及随机访问一连串对象”的做法,array是最有效率的一种。 1、 效率高,但容量固定且无法动态改变。 array还有一个缺点是,无法判断其中实际存有多少元素,length只是告诉我们array的容量。 2、Java中有一个Arrays类,专门用来操作array。         arrays 中拥有一组static函数, equals():比较两个array是否相等。array拥有相同元素个数,且所有对应元素两两相等。 fill():将值填入array中。 sort():用来对array进行排序。 binarySearch():在排好序的array中寻找元素。 System.arraycopy():array的复制。 二、Collection , Map 若撰写程序时不知道究竟需要多少对象,需要在空间不足时自动扩增容量,则需要使用容器类库,array不适用。 1、Collection 和 Map 的区别 容器内每个为之所存储的元素个数不同。 Collection类型者,每个位置只有一个元素。 Map类型者,持有key-value pair,像个小型数据库。 2、Java2容器类类库的用途是“保存对象”,它分为两类,各自旗下的子类关系 Collection         -- List 将以特定次序存储元素。所以取出来的顺序可能和放入顺序不同               --ArrayList/ LinkedList / Vector         -- Set :不能含有重复的元素               --HashSet/TreeSet Map         --HashMap      -- HashTable      -- TreeMap Map----一组成对的“键值对”对象,即其元素是成对的对象,最典型的应用就是数据字典,并且还有其它广泛的应用。另外,Map可以返回其所有键组成的Set和其所有值组成的Collection,或其键值对组成的Set,并且还可以像数组一样扩展多维Map,只要让Map中键值对的每个“值”是一个Map即可。 Collection下 1.迭代器   迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。迭代器通常被称为“轻量级”对象,因为创建它的代价小。 Java中的Iterator功能比较简单,并且只能单向移动: (1) 使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。 注意:iterator()方法是java.lang.Iterable接口,被Collection继承。 (2) 使用next()获得序列中的下一个元素。 (3) 使用hasNext()检查序列中是否还有元素。 (4) 使用remove()将迭代器新返回的元素删除。 Iterator是Java迭代器最简单的实现,为List设计的ListIterator具有更多的功能,它可以从两个方向遍历List,也可以从List中插入和删除元素。 2.List的功能方法 List(interface): 次序是List最重要的特点;它确保维护元素特定的顺序。List为Collection添加了许多方法,使得能够向List中间插入与移除元素(只推荐LinkedList使用)。一个List可以生成ListIterator,使用它可以从两个方向遍历List,也可以从List中间插入和删除元素。 ArrayList: 由数组实现的List。它允许对元素进行快速随机访问,但是向List中间插入与移除元素的速度很慢。 ListIterator只应该用来由后向前遍历ArrayList ,而不是用来插入和删除元素,因为这比LinkedList开销要大很多。 LinkedList: 由列表实现的List。对顺序访问进行了优化,向List中间插入与删除得开销不大,随机访问则相对较慢(可用ArrayList代替)。它具有方法a ddFirst()、addLast()、getFirst()、getLast()、removeFirst()、removeLast() ,这些方法(没有在任何接口或基类中定义过)使得LinkedList可以当作堆栈、队列和双向队列使用。 3.Set的功能方法 Set(interface): 存入Set的每个元素必须是唯一的 ,这也是与List不同的,因为Set不保存重复元素。 加入Set的Object必须定义equals()方法以确保对象的唯一性。 Set与Collection有完全一样的接口。Set接口不保证维护元素的次序。 HashSet:HashSet 能快速定位一个元素, 存入HashSet的对象必须定义hashCode()。 TreeSet :保持次序的Set,底层为树结构。使用它可以从Set中提取有序的序列。 LinkedHashSet :具有HashSet的查询速度,且内部使用链表维护元素的顺序(插入的次序)。于是在使用迭代器遍历Set时,结果会按元素插入的次序显示。 HashSet采用散列函数对元素进行排序,这是 专门为快速查询而设计的 ;TreeSet采用红黑树的数据结构进行排序元素;LinkedHashSet内部使用散列以加快查询速度,同时使用链表维护元素的次序,使得看起来元素是以插入的顺序保存的。需要注意的是,生成自己的类时,Set需要维护元素的存储顺序,因此要实现Comparable接口并定义compareTo()方法。 3、其他特征 *     List,Set,Map将持有对象一律视为Object型别。 *     Collection、List、Set、Map都是接口,不能实例化。       继承自它们的 ArrayList, Vector, HashTable, HashMap是具象class,这些才可被实例化。 *     vector容器确切知道它所持有的对象隶属什么型别。vector不进行边界检查。 三、Collections Collections是针对集合类的一个帮助类。 提供了一系列 静态 方法实现对各种集合的搜索、排序、线程完全化等操作。 相当于对Array进行类似操作的类——Arrays。 如, Collections.max(Collectioncoll); 取coll中最大的元素。         Collections.sort(List list);  对list中元素排序 四、如何选择? 1、容器类和Array的区别、择取        *      容器类仅能持有对象引用(指向对象的指针),而不是将对象信息copy一份至数列某位置。        *      一旦将对象置入容器内,便损失了该对象的型别信息。 2、       *     在各种Lists中,最好的做法是以ArrayList作为缺省选择。当插入、删除频繁时,使用LinkedList();          Vector 总是比ArrayList慢,所以要尽量避免使用。       *     在各种Sets中,HashSet通常优于HashTree(插入、查找)。只有当需要产生一个经过排序的序列,才用TreeSet。          HashTree 存在的唯一理由:能够维护其内元素的排序状态。       *     在各种Maps中          HashMap 用于快速查找。       *     当元素个数固定,用Array,因为Array效率是最高的。   结论:最常用的是ArrayList,HashSet,HashMap,Array。而且,我们也会发现一个规律,用TreeXXX都是排序的。 注意: 1、Collection没有get()方法来取得某个元素。只能通过iterator()遍历元素。 2、Set和Collection拥有一模一样的接口。 3、 List 可以通过get()方法来一次取出一个元素 。使用数字来选择一堆对象中的一个,get(0)...。(add/get) 4、一般使用ArrayList。 用LinkedList构造堆栈stack、队列queue 5、 Map用 put(k,v) / get(k) ,还可以使用containsKey()/containsValue()来检查其中是否含有某个key/value。        HashMap 会利用对象的hashCode来快速找到key。      *     hashing            哈希码就是将对象的信息经过一些转变形成一个独一无二的int值,这个值存储在一个array中。           我们都知道所有存储结构中,array查找速度是最快的。所以,可以加速查找。                   发生碰撞时,让array指向多个values。即,数组每个位置上又生成一个梿表。 6、Map中元素,可以将key序列、value序列单独抽取出来。 使用 keySet() 抽取key序列,将map中的所有keys生成一个Set。 使用 values( ) 抽取value序列,将map中的所有values生成一个Collection。 为什么一个生成Set,一个生成Collection?那是因为,key总是独一无二的,value允许重复。
    转载请注明原文地址: https://ju.6miu.com/read-1304497.html
    最新回复(0)