Java集合框架

1 Java集合框架

1.1 Java集合框架

Java集合框架中分为两大类:装载数据的集合类和操作数据的工具类。

Java集合类是基于Collection接口,再根据不同需求分类为SetListMap三大接口。

Java集合就像一种容器,可以通过相应的方法将多个对象的引用放在容器中。 容器中的元素(对象的引用)类型都为Object类型,所以可以通过向上转型存放任意类型的对象引用,但从容器中取出元素时必须向下转型(强制)为原来的类型。

值得注意的是,集合类容器中的元素不存放基本数据类型,可存放包装类类型。

Java集合框架再实际应用开发中使用非常广泛,属于Java程序员重点掌握的内容。

装载数据的集合类:集合类通过Collection接口定义了集合类共有的一些基本方法,这些方法分为基本操作(添加、删除、修改和查找容器元素)、批量操作(批量添加、删除容器元素)和数组操作(集合与数组转换)

1.2 List接口

List接口:它继承与Collection接口,是一个允许存在重复元素的有序集合。List接口的实现类(具体类)常用的有ArrayList(顺序表集合)和LinkedList(链表集合)。

1.2.1 ArrayList(顺序表集合)

ArrayList(顺序表集合):ArrayList类扩展Abstractlist并实现List接口。ArrayList提供了一个随需要而增长的动态数组。在Java中,标准数组是固定长度的,再数组创建之后,它们不能被加长或缩短,这也就意味我们必须事先知道数组可以容纳多少元素。但是,直到运行时才能知道需要多大数组。ArrayList类就是为了解决这个问题。

特点:对于使用索引查询元素效率较高,它可以使用快速定位元素位置但删除或插入元素效率较低,因为使用了数组,需要移动后面的元素以调整索引的顺序。它的使用最广泛,可在集合元素增加或删除操作不频繁时使用,最适合做查询操作。

 

 

1.2.2 LinkedList(链表集合)

LinkedList(链表集合):LinkedList类扩展AbstractSquentiaList并实现List接口。它提供了一个链表的数据结构。

特点:因为LinkedList是使用双向链表,所以针对频繁的插入和删除元素,使用LinkedList类效率较高。它的使用适合实现栈(数据结构)和队列(数据结构),当需要在集合中间位置频繁增加或删除元素时建议使用LinkedList类。

倒序 reverse

排序 sort

随机 shuffle

复制clone copy

Iterator接口是一种用于遍历集合。所谓遍历,是指从集合中取出每个元素的过程。

boolean hasNext()//判断游标右边是否有元素

Object next()//返回游标右边的元素并将游标移动到下一个位置

void remove()//删除游标左边的元素

实现比较器接口

实现方法

1.2.3 Vector(向量表集合)

Vector(向量表集合):Vector类扩展AbstractSequentialList并实现List接口。与ArrayList的用法几乎完全相同,两者之间最大的区别在于Vector

是线程安全(线程同步),所以性能要稍微低与ArrayList类。该实现类已过时,实际应用开发时,尽量少用。

1.2.4 Stack(栈集合)

Stack(栈集合):Stack类扩展Vector类,它提供了一个栈的数据结构。数据结构中的栈,在解决很多问题都是有用的(比如括号匹配、迷宫求解、表达式求值)该实现类已过时,实际应用开发时,尽量少用。

1.3 Set接口

Set接口:他继承于Collection接口,是一个不允许存在重复元素的有序集合。Set接口添加、查找和删除元素都有很高的效率。Set接口的实现类(具体类)常用的有HashSet(哈希集合)、LinkedHashSet(链表哈希集合)和TreeSet(有序树集合)。

1.3.1 HashSet(哈希集合)

HashSet(哈希集合):HashSet类是Set接口实现类之一,使用较为广泛,它不保存元素的加入顺序,HashSet类根据元素的哈希码进行存放,所以取出时也可以根据哈希码快速找到。注意:因为Set接口中不能加入重复的元素,所以对于自定义类需要提供判断重复元素的方法,即需要重写hashCode()和equals()方法。

hashCode()方法:如果一个集合中有100个元素,再添加一个新元素时,是否需要执行100equals()方法呢?如果每增加一个元素就遍历一次集合,那么当元素很多时,后添加到集合中的元素遍历比较次数就非常多。这样显然会大大降低效率。于是Java采用了哈希表(数据结构)的原理,使用哈希算法(也称为散列算法)将元素直接指定到一个地址上。我们可以讲hashCode方法的返回值看作是对象存储的物理地址的一个索引。添加新元素时,先通过索引查看这个位置是否存在元素,如果不存在,则可以直接将元素存储于此,不需要再调用equals方法;如果已经存在元素,则再调用equals方法与新元素进行比较,相同则不存放,不同就再索引其他地址。这样就使实际调用equals方法的次数大大降低,提高了运算效率。 

equals方法和hashCode方法的说明:

1)如果两个对象相同,那么他们的hashCode(哈希吗)一定要相同;

2)如果两个对象的hashCode(哈希吗)相同,这两个对象并不一定相同。

注意;Java规范字要求,如果程序员重写了equals方法,就一定要重写hashCode方法。当两个对象调用equals方法比较时,如果返回true,那么他们的hashCode值要求返回相等的值。

1.3.2 LinkedHashSet(链表哈希集合)

LinkedHashSet(链表哈希集合):它的使用和HashSet几乎相同,并使用链表记录元素的加入顺序。

 

1.3.3 TreeSet(有序树集合)

TreeSet(有序树集合):TreeSet类使用红黑树(数据结构)对加入的元素进行排序存放,如果加入TreeSet类中的元素时自定义,则需要实现比较器Comparable接口并重写compareTo方法,用于元素之间的排序比较。

整型包装类:按数字大小排序

Character:按Unicode值得数字大小排序

String:按字符串中的字符的Unicode值大小排序

1.4 Map接口

Map接口:它不是继承于Collection接口,用于维护键值对。Map中的键值可以是任意类的实例化对象。再Map中是不允许出现重复的键,所以存入Map中的键对应的类必须重写hashCode()和equals方法。Map接口的实现类(具体类)常用的有HashMapTreeMapProperties

1.4.1 HashMap(哈希映射集合)

HashMap(哈希映射集合):HashMap类是基于哈希表的Map接口实现,提供所有可选的映射操作,效率高,所以在实际应用开发中使用很广泛。由于HashMap的键要求不重复,建议尽量使用标准库类,避免自定义类重写equals方法和hashCode方法。

1.4.2 ThreeMap(有序树映射集合)

ThreeMap(有序树映射集合)ThreeMap类内部使用红黑树(数据结构)对“键”进行排序存放。所以,放入ThreeMap中的键值对必须是可排序的;如果自定义类作为键,name就需要同TreeSet相似,实现Compareable接口并重写compareTo方法。

1.4.3 Properties(属性集合)

Properties(属性集合):Properties累表示一个持久的属性集,他可保存在流中加载。属性列表中每个键及其对应值都是一个字符串。Properties类继承与HashTable,自java2平台(JDK1.2版本)以来,HashTable类已经改进为可以实现Map接口,所以Properties类也具有Map的特性。但是Properties类存放的键值对都是字符串,在存取数据时不建议使用put方法和putAll方法,应该使用setProertyString keyString Value)方法和getPropertyString key)方法。

注意

1)如果涉及到堆栈、队列等操作,应该考虑使用List接口的实现类;

2)如果要进行大量的随机访问,应该使用ArrayList;

3)如果经常进行插入和删除操作,应该使用LinkedList

4)总是使用类型安全的泛型,避免在运行时出现ClassCastException异常;

5)尽量使用使用JDK的标准类作为Map的键(如整型避免自己实现比较器或equals方法和hashCode方法。)

6)尽量使用CollectionsArrays工具类。而非编写自己的实现类。它将会提高代码的重用性,他有更好的稳定性和可维护性。

7)应用开发尽量不要使用过时的VectorHashTablStack

1.5 Java泛型

由于集合中保存的元素都是Object类型,当一个元素从集合中取出来后都是Object类型的对象引用,所以我们必须对其进行向下强制转型,为了解决这种麻烦,JDK1.5中支持一项新特性-Java泛型。

所谓泛型是指在定义(类的定义、方法的定义、形式参数的定义、成员变量的定义等)的时候,指定它为通用类型,也就是数据类型可以是任意的类型,具体调用的时候要将通用类型转换成指定的类型使用。

泛型是对Java语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类,可以把类型参数看作是使用参数化类型时指定的类型的一个占位符,就像方法的形式参数是运行时传递的值的占位符一样。

泛型的优点:Java语言引入泛型的好处是简单安全。泛型的好处是在编译的时候检查类型安全,并且所有的向下强制转型都是自动和隐式的,提高了代码的重用率。

注意:在静态方法、静态初始化块、静态成员变量里面不允许使用泛型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值