Java集合类框架学习

    技术2024-12-30  12

     一. Java集合类概述

    1. 集合类:为了保存数量不确定的数据,以及具有映射关系的数据(关联数组)。集合类主要负责保存和盛装其他数据,因此集合类又叫做容器类。 2. 集合类与数组的区别:

       集合类中的数据数量不确定,而数组中数据的数量确定。

       数组中的数据既可以是基本数据类型,又可以是对象。而集合类中只能保存对象。

    3.Java 集合框架的根接口: Collection Map  

    Map 保存的的每一项数据都是一个 key-value 对,其中 key 是不重复的。 二. Collection 接口和 Iterator 接口          1.Collection 接口 add,addAll,clear,contains,containAll,,remove,removeAll,size,isEmpty,toArray,iterator,re-tainAll          2.Iterator 接口                    Iterator 对象被称为迭代器,用于遍历集合中的元素。                    三个方法: hasNext next remove                    注意:

       使用 Iterator对集合元素进行迭代时,并不是把集合元素本身赋给迭代变量,而是把集合元素的值赋给迭代变量,所以修改迭代元素的值对于集合不会有任何影响。

       使用 Iterator对集合元素进行迭代时,集合元素不能被改变( Iterator remove方法除外),否则会产生异常。

    3.foreach 循环                   利用 foreach 循环也可以遍历集合中的元素。                   Iterator 注意的两点相同。 三. Set 接口

             Set 集合类似于一个罐子,其中的元素无序且不相等。 Set集合判断两个元素是否相等是根据 equal方法,而不是根据“ ==”来判断。

             1.HashSet

                       HashSet 是根据哈希算法来存取集合中的元素。                    HashSet 集合判断两个元素相等的标准是:通过 equals 方法比较两个对象相等,并且 hashCode 方法的返回值也相等。                    注意:

       如果一个类重写 equals方法,那么相应的也要重写 hashCode方法。规则是:如果两个对象通过 equals方法比较返回 true,那么它们的 hashCode方法的返回值也应该相同。

       当向 HashSet集合中添加可变对象时要格外注意,因为通过对可变对象的修改可能会导致 HashSet集合中的两个元素完全相同,但是又处于不同的位置,从而导致 HashSet集合无法准确的访问该对象。

    LinkedHashSet 类,是 HashSet 的子类,与 HashSet 类不同的是,它通过链表维持集合中元素的顺序,使得集合中的元素看起来时按照插入顺序保存的。                    2.TreeSet                             继承了 SortedSet 接口,确保集合中的元素处于排序状态。                             HashSet 类相比增加了如下几个方法:                                      first,last,lower,higher,subset,headSet,tailSet,comparator TreeSet 并不是按照元素的插入顺序进行排序, TreeSet 支持两种排序算法:自然排序和定制排序。 ·自然排序: TreeSet 调用元素的 compareTo 方法来比较元素的大小关系,然后按照升序排列。如果试图将一个对象加入 TreeSet 集合,那么这个对象所对应的类必须实现 Comparable 接口,否则会抛出异常。向 TreeSet 集合中加入的必须是同一类型的对象,否则也会抛出异常。 TreeSet 集合中两个对象完全相同的标准是:通过 equals 方法比较返回 true ,并且同 compareTo 方法比较返回 0. 当向 TreeSet 中加入可变对象时要格外注意,对可变对象修改后,排序不会发生变化,删除元素也可能会失败,因为 TreeSet 中可能存在两个完全相同的元素。

    总之,不要向 HashSet TreeSet 中加入可变对象。

    ·定制排序:通过 Comparator 接口实现。加入 TreeSet 集合中的元素没有必要再实现 Comparable 接口,但是加入加入 TreeSet 集合中的元素仍然需要是同一类型。                    3.EnumSet                             EnumSet 是专为枚举类设计的集合类, EnumSet 集合的元素必须为指定枚举类型的枚举值。                           EnumSet 没有暴露任何构造方法来构造该类的对象,要构造该类的对象必须通过 EnumSet 本身提供的静态方法。                             主要的静态方法如下:                             allOf,noneOf,of,range,copyof(EnumSet),copyOf(Collection),complementOf                    如何选择实现 Set 接口的各个类:                    · HashSet 类的性能总是比 TreeSet 类的性能要好,而 TreeSet 类在需要排序时才使用。                    · HashSet 类的性能比 LinkedHashSet 类的性能也要略好一些,但是 LinkedHashSet 类在遍历集合元素时要快一些。                    · EnumSet 是所有的 Set 实现类中性能最好的,但是只能保存枚举类型的元素。                    · Set 实现类都不是线程安全的。 四. List 接口          List 是一个有序的集合, List 集合中的每一个元素都有其对应的索引,所以 List 集合中的元素允许重复。 List 按照添加元素的先后顺序设置索引。          1.List 接口与 ListIterator 接口                    Collection 接口不同, List 接口中增加一些根据索引操作元素的方法。                    List 接口中的方法:                    ·添加元素: add(Object),add(index,Object),addAll(Collection),addAll(index,Collection)                    ·删除元素: remove(Object),removeAll(Collection),remove(index)                    ·获取元素: get(index)                    ·替换元素: set(index,Object)                    ·截取元素: subList(fromIndex,toIndex)                    ·返回索引值: indexOf(Object),lastIndexOf(Object)                    ListIterator 接口是 Iterator 接口的子接口,它增加了一些新的方法,专门用来操作 List 集合。                    ListIterator 接口中新增加的方法有:                    · hasPrevious()                    · previous()                    · add()          2.ArrayList Vector 实现类                    ArrayList Vector 类都是基于数组实现的,所以 ArrayList Vector 都封装了一个动态分配大小的数组 Object[] ArrayList Vector 类都有一个属性 capacity ,表示它们封装的数组 Object[] 的大小, capacity 会随集合中元素的个数变化而自动变化。                    ArrayList Vector 类可以通过以下方法来操作 capacity 属性:                    · ensureCapacity(minCapacity)                    · trimToSize()                    Vector 类提供了一个子类 Stack 类用来模拟“栈”这种数据结构。 Stack 具有的方法如下:                    · push(Object)                    · pop()                    · peek()          3. 固定长度的 List                    Arrays.ArrayList 类:可以将一个数组或者指定个数的对象转换成一个 List 集合。不能进行插入和删除操作,只能遍历。 五. Queue 接口          Queue 接口模拟队列这种特殊的数据结构,主要的方法如下:                    add(),offer(),element(),peek(),poll(),remove()          1.LinkedList 实现类                    LinkedList 类既可以当做双向队列来使用,也可以当做栈来使用,还可以当做 List 集合来使用。                    LinkedList 类与 ArrayList Vector 类的实现机制完全不同, ArrayList Vector 类内部是以数组的形式保存元素,所以随机访问性能较好,而 LinkedList 类是以链表的形式保存元素,所以随机访问性能较差,但是在迭代访问元素,插入、删除元素方面性能较好。                    关于 List 集合实现类的选择问题:

    ·  如果需要遍历集合中的元素,对于 ArrayList Vector 类最好使用随机访问( get() )的方法,对于 LinkedList 类最好使用迭代器遍历。

    ·  如果需要经常执行插入和删除操作来改变集合的大小,则应该选用 LinkedList 类,而不要使用 ArrayList 类和 Vector 类。

    ·  如果需要多条线程同时访问 List 集合,则可以考虑使用 Vector 类来同步实现。

    2.PriorityQueue 实现类          对于 PriorityQueue 集合中的元素也是按照大小排序,排序的规则与 TreeSet 类相同,也分自然排序和定制排序两种。 六. Map 接口          首先可以将 Map 接口理解成一个特殊的 Set 接口,只是该 Set 接口中保存的元素都比较特殊,每个元素都是一个 Entry 对象, Entry 类封装了一个 key-value 对,它有三个方法:

             · Object getKey()

             · Object getValue()

             · Object setValue(value)

             其次也可以将 Map 接口理解成一个特殊的 List 接口,只是 List 接口中用整数值做索引,而 Map 接口中用 key 值做索引, key 可以为任意对象。          Map 接口用于保存映射数据,它里面保存有两组数据,一组用来保存 key ,一组用来保存 value Key 不允许重复。 Map 有时也被称为字典或者关联数组。          Map 接口提供的方法:

             ·添加元素: put(Object key,Object value),putAll(Map m)

             ·删除元素: remove(Object key)

             ·清除所有元素: clear()          ·获取元素: get(Object key)          ·测试: containsKey(key),containsValue(value),isEmpty()          ·集合大小: size()

             ·转化: Collection values(),Set keyset(),Set entrySet()

             1.HashMap Hashtable                    HashMap 类和 Hashtable 类的关系就像 ArrayList Vector 类的关系一样。                    HashMap Hashtable 类的区别:                    · Hashtable 是一个线程安全类,而 HashMap 不是线程安全的。但是 HashMap 性能比 Hashtable 性能高一些。                    · Hashtable 不允许 null 作为 key 或者 value ,而 HashMap 允许。但在 HashMap 集合中最多有一个 key null ,但是可以有多个 value null                    HashMap Hashtable 类也不能保证其中 key-value 对的顺序,但是它们中的 key 必须实现 equals hashCode 方法。                    HashMap Hashtable 类判断两个 key 值是否相等标准:通过 equals 方法比较返回 true ,并且具有相同的 hashcode                    HashMap Hashtable 类判断两个 value 值是否相等标准:通过 equals 方法比较返回 true                    HashSet 类似,尽量不要使用可变对象作为 HashMap Hashtable key                    HashMap 的子类 LinkedHashMap :与 HashMap 不同的是它可以维护元素的迭代顺序,在性能上略差于 HashMap ,迭代速度却高于 HashMap                    Hashtable 的子类 Properties 类:                    Properties 类用来将 Map 对象与属性文件关联起来,从而可以将 Map 对象中的 key-value 对加入到属性文件,同时也可以将属性文件中的内容加入到 Map 对象中。                    由于属性文件中的“属性名”和“属性值”都是字符串类型,所以 Properties 文件中的 key value 也都是字符串类型。                    Properties 类主要提供如下几个方法:

                       · String getProperty(String key)

                       · String getProperty(String key,String defaultValues)

                       · void setProperty(String key,String value)

                       · void load(InputStream is)

                       · void store(OutputStream os,String comments)

             3.SortedMap 接口和 TreeMap 实现类                    SortedSet 接口和 TreeMap 实现类完全类似。          4.WeakHashMap 实现类                    WeakHashMap 类与 HashMap 类基本相同,不同的是 HashMap key 保留了对实际对象的强引用,而 WeakHashMap 类的 key 保留了对实际对象的弱引用。          5.IdentityHashMap                    IdentityHashMap 类与 HashMap 类基本相同,不同的是 IdentityHashMap 类在判断 key 值相等时,必须保证代表 key 值的两个对象完全相等时才认为是相等的。          6.EnumMap                    EnumMap 是一个与枚举类一起使用的 Map 实现,它要求 key 值必须是一个枚举类的枚举值,创建 EnumMap 类时必须显示或者隐式的指定它对应的枚举类。                    EnumMap 不允许使用 null 作为 key 值,但是允许 null 作为 value 值。          Map 集合的选择问题:          · HashMap Hashtable 类的效率基本相同,但 HashMap 的性能可能比 Hashtable 要好一些,因为 HashMap 没有实现同步操作。          · TreeMap 类的性能不如 HashMap ,但是 TreeMap 类中的 key-value 对都是有序的。          · LinkedHashMap 的性能比 HashMap 略差一点,因为它要维护 key 的插入顺序。          · EnumMap 的性能最好,但是它要求必须要将一个枚举类中的元素作为 key 七. HashSet HashMap 的性能选项          桶: hash 表中可以存储元素的位置。          HashSet HashMap hash 表都有以下性能选项:          ·容量( capacity ): hash 表中桶的数量          ·初始化容量( initialCapacity ):创建 hash 表时指定的桶的数量。          ·尺寸( size ):当前散列表中记录的数量          ·负载因子( loadFactor ): size/capacity ,轻负载的散列表具有冲突少,插入方便,易查询的优点。          负载极限:负载极限的值在 0-1 之间,当超过负载极限时,会成倍的增加容量( rehashing )。 八.操作集合的工具类 Collections          Java 提供了一个操作 Set List Map 等集合的工具类: Collections          1. 排序操作                    Collections 提供了一下几个方法用于对 List 集合进行排序(都是静态的):                    · reverse(list) :反转集合中的元素                    · shuffle(list): 对集合中的元素进行随机排序                    · sort(list) :根据自然顺序对集合中的元素进行排序                    · sort(list,comparator) :根据定制顺序对集合中的元素进行排序                    · swap(list,i,j) :将 i j 处的元素进行交换                    · rotate(list,i): i list.length-1-i 处的元素进行交换          2. 查找、替换操作                    Collections 提供了一下几个方法用于对 List 集合进行查找、替换(都是静态的):                    · binarySearch(list,object) :查找指定元素在 list 中的索引,但执行此方法前必须保证 list 已经处于有序状态。                    · max(collection): 按照自然排序查找 collection 中的最大值                    · max(collection,comparator): 按照定制排序查找 collection 中的最大值                    · min(collection): 按照自然排序查找 collection 中的最小值

                       · min(collection,comparator): 按照定制排序查找 collection中的最小值

                       · fill(list,object): 使用指定元素 object 替换 list 中的所有元素                    · frequency(colletion,object): 返回集合 collection object 元素出现的次数                    · replaceAll(list,oldval,newval): 用新的元素 newval 替代 list 中所有旧的元素 oldval          3. 同步控制                    Collections 提供了多个 synchronizedXxx 方法用来同步集合对象,可以解决多线程并发访问集合时的线程安全问题。          4. 设置不可变的集合                    Collections 提供了三个方法返回一个不可变的集合:                    · emptyXxx(): 返回一个空的不可变的集合对象。                    · singleton(object): 返回一个只包含一个元素 object 的集合对象。

                       · unmodifiableXxx(colletion or map): 返回一个不可变的视图。

     

    本文出自 “duanruihaoren专栏 ” 博客,请务必保留此出处http://duanruihaoren.blog.51cto.com/2448130/487932

    最新回复(0)