Java集合

声明:本文章经过别人文章摘要整理而来,并非纯原创作品!
  • 集合框架
    •    对于对象集合,必须执行的操作主要以下三种:
      •  添加新的对象
      •  删除对象
      •  查找对象
  1. 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
  1. HashMap
  2. LinkedHashMap
  3. 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允许重复。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值