java容器使用_Java中容器的使用

5e8cb29230a5190bcad056663c9c5b85.png

由上面的图可以非常清楚的看到,Java中的容器的继承结构

在顶层有很多接口,这些接口声明了很多的基本的抽象方法,之后的许多类按照不同的方式实现这些接口,

同时可能在增加一些自己的方法,从而形成了不同功能的容器,比如:ArrayList类与LinkedList类都继承了List接口,

但是他们在实现List的接口时,方法体并不一样,这样一来就形成了不一样的容器,这些容器都位于java.util包中

接下来我们将一一介绍这些容器的功能,当然我们不可能将容器的所有的知识全部不漏的讲解,我们只是将一些

思想讲解一下,使我们对容器有一个整体的认识,至于一些具体的方法如何使用,需要在用时查询官方文档

首先我们先对List、Set、Queue、Map接口的功能做一个介绍:

①List类型的容器实际上就相当于一个长度可变的

“对象数组”,和向量的概念是相同的

②Set类型的容器实际上相当于一个“对象集合”

这样的容器中是不允许加入重复的元素的,并且

对于其中的元素并没有一种排序的概念,和集合

是一个概念

③Queue类型的容器实际上相当于一个“对象队列”

④Map类型的容器中的每个元素包含一对儿键对象和

值对象,即在关键字对象和值对象之间产生一种映射关系,通过键对象类查找值对象

接下来,我们介绍逐一介绍这些具体的容器都有什么功能

实例:

Collection c = new ArrayList

(Array.asList("A","B","C"));

一、Collection 接口

这个接口只一个抽象度非常高的接口,这其中声明了那些实现了他的容器类都具有的特性方法,也就是诸如:

ArrayList类、LinkedList类、HashSet类等其中的继承自Collection接口的方法的实现方式都是一样的,

比如:boolean add(E e) 这个方法在所有的这些类中都是将一个元素加入容器当中;

即Collection中的抽象方法都是从“一堆元素”的概念上抽象出来的Collection接口的常用抽象方法有:

① public Boolean add(E e)

向容器当中添加一个元素

②boolean addAll(Collection extends E> c)

向当前的容器中加入指定的Collection类型的容器的所有元素

③void clear()

移除容器当中的所有的元素

④boolean contains(Object obj)

判定当前的容器中是否有指定的元素,我们想肯定调用了equals()方法了

⑤boolean containsAll(Collection> c)

判定当前容器中是否包含了,指定的容器中的所有的元素

⑥boolean isEmpty()

判定当前的容器是否为空

⑦Iterator iterator()

返回当前容器对应的迭代器

⑧boolean remove(Object obj)

如果容器当中含有该元素,则将之删除

⑨boolean retainAll(Collection> C)

将当前的容器中的元素和指定的容器元素取交集存入当前容器中

10.int size ()

返回容器的元素数目

11.Object[] toArray()

根据当前容器中的元素创建一个对象数组

二、实用类Collections

在上面的图中的右下角有两个实用类:Collections类

和Arrays类,Arrays类中的静态方法主要是操作数组的,而Collection类中也有很多静态的方法是用来操作List、Set、Queue、Map类型的容器的,

这两个实用类都位于java.util包中

在Arrays类中也有一个操纵容器的方法

static    List

asList(T... a)

返回有可变参数列表创建的List类型的容器对象,并返回容器的引用,如:

String [] strArray = {“123”,”wr”,”fsdf”};

List ls = Array.asList(strArray);

在Collection类中的静态方法,能够实现容器中元素的替换、删除、排序、整个复制等等,具体的就不在多讲

三、List(列表)

像数组一样,List也能建立数字索引与对象的关联,表达的是数据结构中的线性表的概念,List接口的常用实现类是:ArrayList和LinkedList

①ArrayList类

就像名子显示的那样,ArrayList是线性表中的数组,也就是说这个类中的数据域实际上就是一个对象数组,

因此,他有数组的一切的特性,还有同时封装在一起的方法

因此对于查找来说,速度是非常的快的,但是删除与插入操作就相对较慢,而且ArrayList是线程不安全的

②LinkedList类

就像名字显示的那样,LinkedList是线性表当中的链表,也就是说这个类中的数据域实际上就是一个对象链表,

还有同时封装在一起的方法,值的注意的是内部的这个链表是一个双向的循环链表,

也就是说,插入语删除操作是非常快的,但是查找较慢

另外需要非常注意的是,LinkedList类还继承了Queue接口,

LinkedList类中单独还有addFirst()、addLast()、getFirst()、getLast()、removeFirst()、removeLast()等方法,

这就是的LinkedList类的对象能够用作队列和栈来使用,同样,LinkedList是线程不安全的

四、Set(集合)

1、Set 中不接受任何重复的元素,如果试图将重复的对象加到同一个Set对象当中的话,是不能加入的;所谓的相同的对象,

是根据equals(参数)方法来判定的,这就要涉及到该方法的重写问题了,这在之前已经讨论过了

2、一般Set最常用于判定一个指定元素的归属性问题,即判定一个元素是否已经在在当前的集合当中了!可见查找

是Set型容器的最常用的、最重要的方法了;Set与Collection具有完全一样的接口,实际上Set就是Collection,只是应用的行为不同罢了!

3、虽然Set有HashSet、TreeSet、LinkedSet三种实现类,但是在《thinking in java》 中明确指出,

对于查找而言HashSet类失效率最高的一个类,所以在没有特殊的要求时,使用HashSet是最好的选择

1、这个类的内部有一个HasMap实例对象作为其成员域,

这说明在HashSet类的实例对象中的元素都是按照哈希表的形式存储在HashMap对象中了,这也就说明了,HashSet类的查找效率是非常高的

2、通过add(参数)向HashSet对象当中,添加元素时,首先会调用hasCode()方法,计算出该元素的存放位置,

比较该位置的元素是否与要添加的元素相同,所以又要调用equals()方法;同时在查找时也要调用hashCode方法;

这就要求我们将equals()方法和hashCode方法同时重写,保证两个方法相匹配,即保证:

当两个元素对象“相等时”,那么两个元素对象应该生成相同的散列码

这就用到了另一份文档“Java中的hashCode()方法的深入剖析.doc”(其中那个例子非常有代表性)

我们在获得这个容器中的每个元素时,可以使用简化的for语句实现,这是允许的,可以查阅一下简化的for语句的使用前提

五、Queue(队列)

也就是说,Queue类型的容器专门用来用作容器来使用的

具有队列的特性

①利用LinkedList类型的容器实现普通的队列、双向队列、栈等数据结构(LinkedList类同时实现了Queue接口),

我们可以通过将LinkedList的对象向上转型到Queue,这样一来的话就只能使用继承自Queue接口的专门用于队列的方法,

使LinkedList对象看起来像一个完完全全的队列容器;对于双向队列,java中有一个专门用于实现双端队列的接口Deque,位于java.uitl包中,

而且LinkedList类也实现了该接口,所以同样可以将LinkedList对象向上转型形成一个单纯的双端队列

②PriorityQueue(优先级队列)

所谓的优先级队列就是在该队列的内部有一个堆的数据结构,实现了每次出对的元素,都是优先级最高的元素;

但是程序是如何知道每个元素的优先级的呢,这里有两种方式:自然方式和人为指定方式

所谓的自然方式是指,如果容器中的元素对象是String、Integer、或者是Character类型的内嵌数据类型的话,

那么这种优先级是程序已经自行规定好的了,即“较小”的拥有较高的优先级;但是对于实际问题中的很多的元素都不是内嵌的数据类型,

那么就要人为的指定优先级的设定规则,解决这一问题的方法就是,使元素类实现Comparable

接口,这个接口中只有一个方法

public int compareTo(Object obj)

只要在元素类中将该方法实现的话,那么程序就会自行的根据这个方法来设定优先级,如:

4c19d21a5c8473f4d5e1e575f2fb0be0.png

注意:对于PriorityQueue来说,他的遍历器不能保证按照优先级次序便利所有的元素

六、Map(映射)

Map(映射)是一种将键对象和值对象进行映射的集合,需要注意的是如果值对象是Map类型的话那么,就形成了多级映射;

在实现该接口的类中效率最高的一个就是HashMap类,一般在没有特殊的要求的情况下最好及使用这个类型的容器,

这个容器的用法和前面讲过的Hashtable容器非常相近,可以参照该部分的内容进行理解,

其中最终要的一点是对于hashCode()和euqals()方法的重写;

另外需要注意的一点是:如果在哈希表的应用中,迭代性能比查找性能更加站上风,那么在设定初始容量时,

就应该尽量的不让初始容量太高,而同时让装填因子设定的得尽量的高;如果是说实际使用哈希表的时候,

有非常多的键值对要加入到该容器中的话,使用足够大的初始容量创建该容器,将使得映射关系更加有效的存贮,

因为如果初始容量设定的过于小的话,那么容器就会按照规则不断的进行扩充,那么就会耗费非常多的时间

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值