一. Java集合类概述
1. 集合类:为了保存数量不确定的数据,以及具有映射关系的数据(关联数组)。集合类主要负责保存和盛装其他数据,因此集合类又叫做容器类。 2. 集合类与数组的区别:① 集合类中的数据数量不确定,而数组中数据的数量确定。
② 数组中的数据既可以是基本数据类型,又可以是对象。而集合类中只能保存对象。
3.Java 集合框架的根接口: Collection 和 MapMap 保存的的每一项数据都是一个 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