设为首页 加入收藏

TOP

Java集合框架(Collections Framework)(一)
2017-11-13 14:55:32 】 浏览:475
Tags:Java 集合 框架 Collections Framework

集合和数组的区别:


严格地说,集合是存储对象的引用,每个对象都称为集合的元素。根据存储时数据结构的不同,分为几类集合。但对象不管存储到什么类型的集合中,既然集合能存储任何类型的对象,这些对象在存储时都必须向上转型为Object类型,也就是说,集合中的元素都是Object类型的对象


既然是集合,无论分为几类,它都有集合的共性,也就是说虽然存储时数据结构不一样,但该有的集合方法还是得有。在java中,Collection接口是集合框架的根接口,所有集合的类型都实现了此接口或从其子接口中继承。


根据数据结构的不同,一些collection允许有重复的元素,而另一些则不允许。一些collection是有序的,而另一些则是无序的。


Java SDK不提供直接继承自Collection的类,Java SDK提供的类都是继承自Collection的"子接口"如List和Set。也就是说,无法直接new一个collection对象,而是只能new一个实现Collection类的子接口的对象,如new ArrayList();


Java集合框架(Collections Framework)


所有的Collection类都必须至少提供两个构造方法:无参数构造方法构造一个空集合;带Collection参数的构造方法构造一个包含该Collection内容的集合。例如,ArrayList就有3个构造方法,其中之二就满足这两个构造方法的要求。


Collection是java.util包中的类,因此要实现集合的概念,需要先导入该包。


ArrayList继承自List接口,List接口又继承自Collection接口。ArrayList类存储的集合中,元素有序、可重复


因为Collection接口不允许直接实现,因此需要通过实现它的子类来实现集合的概念,此处创建的是ArrayList对象,使用了父类引用,好处是扩展性较好。


Collection有一些集合的通用性操作方法,分为两类:一类是普通方法;一类是带有All的方法,这类方法操作的是集合。


因为不同类型的集合存储数据时数据结构不同,想要写一个通用的遍历集合的方法是不现实的。但无论是哪种类型的集合,只有集合自身对集合中的元素是最了解的,因此在实现Collection接口时,不同集合类都实现了自己独有的遍历方法,这称为集合的迭代器Iterator。其实Collection继承了java.lang.Iterable接口,该接口只提供了一个方法:iterator(),只要是实现了这个接口的类就表示具有迭代的能力,也就具有foreach增强遍历的能力。


迭代器自身是一个接口,通过Collection对象的iterator()方法就可以获取到对应集合类型的迭代器。例如:


Iterator接口提供了3个方法:


虽然有不同种类型的集合,但迭代器的迭代方法是通用的。例如,要遍历coll集合中的元素。


但是通常来说,上面的遍历方式虽然正确,但下面的遍历方式更佳。因为it对象只用于集合遍历,遍历结束后就应该消失,所以将其放入到for循环的内部,由于for循环的第三个表达式缺失,所以不断地循环第二个表达式即可。


通过Iterator遍历到的元素是集合中的一个对象,对象也是有属性的。如何引用这些属性?只需将遍历出的元素作为对象来使用即可,但由于next()返回的元素都是Object对象,直接操作这个元素对象无法获取对应元素中的特有属性。因此必须先强制对象类型转换。


例如,获取coll中为Student对象元素的name属性,并删除非Student对象的元素。


因为集合中有些非Student对象元素,因此需要判断it.next()是否满足instanceof的要求,但不能直接写为下面的代码:


因为每执行一次it.next(),元素的游标指针就向下滑动1,在这个写法中if判断表达式中使用了一次it.next(),在if的代码块中又调用了一次it.next()。所以应该将it.next()保存到对象变量中。而it.next()返回的类型是Object类型,因此定义Object obj = it.next()


只有remove()方法是Iterator迭代器迭代过程中修改集合元素且安全的方法。以迭代时add()为例,当开始迭代时,迭代器线程获取到集合中元素的个数,当迭代过程中执行add()时,它将采用另一个线程来执行(因为add()方法不是Iterator接口提供的方法),结果是元素个数就增加了,且导致新增的元素无法确定是否应该作为迭代的一个元素。这是不安全的行为,因此会抛出ConcurrentModificationException异常。而remove()方法是迭代器自身的方法,它会使用迭代器线程来执行,因此它是安全的。


对于List类的集合来说,可以使用Iterator的子接口ListIterator来实现安全的迭代,该接口提供了不少增删改查List类集合的方法。


List接口实现了Collection接口。


List接口的数据结构特性是:


ArrayList类的方法和List方法基本一致,所以下面介绍了List通用方法和ListIterator就没必要介绍ArrayList。但LinkedList比较特殊,所以独立介绍。


除了因为继承了Collection而具有的通用方法外,对于List接口也有它自己的通用方法。一般List的这些通用方法针对的是序列的概念。有了序列和下标索引值,可以精确地操控某个位置的元素,包括增删改查。


因为有了get()方法,除了Iterator迭代方式,还可以使用get()方法遍历集合:


但注意,这种方法不安全,因为l.size()是即时改变的,如果增删了元素,size()也会随之改变。


示例:


上面的代码中,如果将ls.add(new Student("Malong4",24));的注释取消,将抛出异常,因为Iterator迭代器中唯一安全操作元素的方法是Iterator接口提供的remove(),而add()方法是List接口提供的,而非Iterator接口的方法。但对于List集合类来说,可以使用ListIterator迭代器,它提供的操作元素的方法更多,因为是迭代器提供的方法,因此它们操作元素时都是安全的。


通过listIterator()方法可以获取ListIterator迭代器。该迭代器接口提供了如下几种方法:


例如:前文示例在Iterator迭代过程中使用List的add()添加元素抛出了异常,此处改用ListIterator迭代并使用ListIterator提供的add()方法添加元素。


LinkedList类的数据结构是链表类的集合。它可以实现堆栈、队列和双端队列的数据结构。其实实现这些数据结构都是通过LinkedList提供的方法按照不同逻辑实现的。


提供的其中几个方法如下:因为是实现了List接口,所以除了下面的方法,还有List接口的方法可用。


队列是先进先出FIFO的数据结构。封装的队列类MyQueue代码如下:


操作该队列数据结构程序代码如下:


Set接口也实现了Collection接口。它既然能单独成类,它和List集合的数据结构一定是大有不同的。


Set接口的数据结构特性是:


HashSet的用法没什么可解释的,方法都继承自Set再继承自

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Go 程序的性能优化及 pprof 的使用 下一篇线性表的基本操作及其作用

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目