`
xjk2131650
  • 浏览: 57400 次
  • 性别: Icon_minigender_1
  • 来自: 河北
社区版块
存档分类
最新评论

深入了解 Dojo 的 Collections 工具包

阅读更多

Dojox 的 Collections 工具,一个模拟 Java 的某些实用数据结构的工具包,如:List(ArrayList)、Set、Dictionary、Queue、Stack、BinaryTree 等。这些工具对那些需要用到一些高级 Collections 功能的开发者非常有用。如果您是一位 Java 开发者,您一定对这些数据结构非常熟悉,基于这些工具进行 web 应用开发也将会游刃有余的多。这篇文章将主要来介绍 Dojox.collections 的特性以及一些使用上的技巧。

简介

Dojo 的 collections 工具包的存在主要是提供给开发人员一些比起基本的集合对象(collections)来说,功能更为丰富,使用起来也更加方便的集合对象,如 ArrayList、Dictionaries 等等。Dojo 的这些 collections 对象有点类似于 Java 的 collection 工具集(如“java.util.Collection”接口的那些派生类),并且同 Java 的类库一样,它们有比较完善的接口,性能上也做过优化。在 web 开发中使用这些对象会带给我们比较理想的效果。

Dojo 的 Collection 工具包基础

由于我们接下要介绍的主要是集合对象,所以我们需要先了解一下相关的迭代器和元素对象,这也就是 collection 的基础内容。

DictionaryEntry

所有关于 Dictionary 类集合的迭代元素均为 DictionaryEntry。参考如下代码:


清单 1. DictionaryEntry
				 
 var d=new dojox.collections.DictionaryEntry("foo","bar"); 
 t.assertEqual("bar", d.valueOf()); 
 t.assertEqual("bar", d.toString()); 

其中“t.assertEqual”是 Dojo 中用来判断两个值是否相等的,根据代码可以看出,“DictionaryEntry”有键(key)和值(value)组成,它有两个主要的方法:“valueOf”和“toString”,均可以取得它的值。

Iterator

Iterator 是一个迭代器,相信大家都不陌生了吧,很多编程语言里面都有同名的迭代器,虽然 JavaScript 并没有,不过 Dojo 模拟了一个。参考如下代码:


清单 2. Iterator
				 
 var itr=new dojox.collections.Iterator(["foo","bar","baz","zoo"]); 
 t.assertEqual("foo", itr.element);//test initialization 
 t.assertTrue(!itr.atEnd()); 
 t.assertEqual("foo", itr.get());//make sure the first get doesn't advance. 
 t.assertEqual("bar", itr.get()); 
 t.assertEqual("baz", itr.get()); 
 t.assertEqual("zoo", itr.get()); 
 t.assertTrue(itr.atEnd()); 
 t.assertEqual(null, itr.get()); 

其用法和其它语言的 Iterator 类似,“itr.element”适用于取得当前元素,即 Iterator 迭代指针当前指向的元素,注意:这种用“.element”取值的方式不会造成迭代指针 的位移,指针指向的位置不变。但是,“get()”方法就不是了,每调用一次“get”方法,除了返回当前元素外,还会让指针后移一位,当指针移到末尾时,会有“itr.atEnd()”为真,此时的“itr.get()”则返回 null。

除此以外 Iterator 还支持“map”操作,其本质就是“dojo.map”,参考如下代码:


清单 3. Iterator 配合 map
				 
 var a=itr.map(function(elm){ 
 return elm+"-mapped"; 
 }); 

同“dojo.map”一样,这里的 Iterator 里面的每个节点的内容都加上了“-mapped”的尾椎。还有:“reset”方法可以让指针回到起始位置,进行新的迭代。

DictionaryIterator

想必大家根据名字就能看出来,这个是专门迭代 Dictionary 类集合的,参考如下代码:


清单 4. DictionaryIterator
				 
 var itr=new dojox.collections.DictionaryIterator({ 
 first:"foo", second:"bar", third:"baz", fourth:"zoo"
 }); 
 t.assertEqual("foo", itr.element);//test initialization 
 t.assertTrue(!itr.atEnd()); 
 t.assertEqual("foo", itr.get());//make sure the first get doesn't advance. 
 t.assertEqual("bar", itr.get()); 
 t.assertEqual("baz", itr.get()); 
 t.assertEqual("zoo", itr.get()); 
 t.assertTrue(itr.atEnd()); 
 t.assertEqual(null, itr.get()); 

这里似乎和 Iterator 类似,事实上,DictionaryIterator 的迭代主要是基于“值”的迭代,所以这里的使用方式和返回值几乎相同,而且 DictionaryIterator 也支持“map”操作。

接下来我们来看看 Dojo 所支持的各种集合对象。

ArrayList

做过 Java 开发的软件工程师对这个对象应该再熟悉不过了。我们来看看它的一些示例代码:


清单 5. ArrayList 基本操作
				 
 var al=new dojox.collections.ArrayList(["foo","bar","test","bull"]); 
 t.assertEqual(4, al.count); 
 al.add("carp"); 
 t.assertEqual("foo,bar,test,bull,carp", al.toString()); 
 al.addRange(["oof","rab"]); 
 t.assertEqual("foo,bar,test,bull,carp,oof,rab", al.toString()); 

“count”代表元素数量,“add”用于添加元素,“addRange”可以添加一系列元素(其传入值为数组),它的“toString”方法相当于 JavaScript 的“join(",")”。大家是不是有一种似曾相识的感觉?不错,这些方法和返回结果与我们之前用过的 Java 的 Util 工具包里面的 ArrayList 类非常相似。所以,如果您基于 Dojo 的 ArrayList 做开发,可能您根本用不着了解 JavaScript 的相关语法和接口。

当然,不止这些接口,Dojo 的 ArrayList 还支持很多其它常用接口,如 clone、clear、indexOf 甚至 contains,相信大家在 Java 里面也用过,这里就不赘述了。

接下来我们来看看 Dojo 的 ArrayList 的一些高级的操作方法:


清单 6. ArrayList 高级操作
				 
 var al=new dojox.collections.ArrayList(["foo","bar","test","bull"]); 
 t.assertEqual("test", al.item(2)); 

 var al=new dojox.collections.ArrayList(["foo","bar","test","bull"]); 
 al.insert(2, "baz"); 
 t.assertEqual(2, al.indexOf("baz")); 

 var al=new dojox.collections.ArrayList(["foo","bar","test","bull"]); 
 al.remove("bar"); 
 t.assertEqual("foo,test,bull", al.toString()); 

 var al=new dojox.collections.ArrayList(["foo","bar","test","bull"]); 
 al.removeAt(3); 
 t.assertEqual("foo,bar,test", al.toString()); 

“item”方法用于取值,它使得对于像 ArrayList 这样的集合同样可以通过“数组”的方式来取值,“item(2)”表示取第 2 个元素。同样,插入,删除等等操作也是支持的:“insert(2, "baz")”表示在第 2 位插入“baz”。删除可以通过两种方式:“remove”和“removeAt”,一个通过元素值定位,一个通过下标定位。

还有“reverse”和“sort”方法,一个用于集合的反转,一个用于排序,推荐大家关注一下。

最后,我们来看看它的迭代器用法:


清单 7. ArrayList 的迭代器
				 
 var al=new dojox.collections.ArrayList(["foo","bar","test","bull"]); 
 var itr=al.getIterator(); 
 while(!itr.atEnd()){ 
 itr.get(); 
 } 
 t.assertEqual("bull", itr.element); 

和很多其它语言一样,通过“getIterator”拿到迭代器进行迭代,清单 7 中的代码是不是非常熟悉,我们好像写过太多类似的代码了。

BinaryTree

BinaryTree 也是一个线性结构,它的优势在于它的检索。它的基本操作(包括增删查改)与 ArrayList 基本无异,这里我们主要介绍一下它的检索操作:


清单 8. BinaryTree 检索
				 
 var bt=new dojox.collections.BinaryTree("foo"); 
 bt.add("bar"); 
 bt.add("baz"); 
 bt.add("buck"); 
 bt.add("shot"); 
 bt.add("apple"); 
 t.assertEqual("buck", bt.search("buck").value); 

“bt.search("buck")”这里得到的不是值本身,而是一个节点对象,它有“left”,“right”和“value”等等属性,这里的“value”就是它的值。

BinaryTree 的接口很简单,但是里面的实现比较丰富。每一个外部的“add”操作都会促使它进行二叉树的构造,用于以后的查找。所以它的“search”(包括“contains”)方法的效率非常高,复杂度应该是 O(logn),而 ArrayList(“contains”方法)的复杂度应为 O(n)。但是这样也有缺点:就是 BinaryTree 的 add、deleteData 等方法需要消耗更多的时间。可以说,BinaryTree 比较适合存储并检索大量数据。

我们来参考一下 BinaryTree 的 add 方法的源代码:


清单 9. BinaryTree 的 add 方法实现
				 
 this.add=function(data){
	var n=new node(data);
	var i;
	var current=root;
	var parent=null;

//定位待插入元素在二叉树中的插入位置
	while(current){
		i=current.compare(n);
		if(i==0){ return; }
		parent=current;
		if(i>0){ current=current.left; }
		else{ current=current.right; }
	}
	this.count++;

//插入待插入元素到相应位置
	if(!parent){
		root=n;
	}else{
		i=parent.compare(n);
		if(i>0){
			parent.left=n;
		}else{
			parent.right=n;
		}
	}
};


参照代码中的注释,可以看出 BinaryTree 的每一个外部的“add”操作是如何进行二叉树的构造的。

Queue & Stack

Queue 和 Stack 也都是线性结构,我们学数据结构时可能对 Queue 和 Stack 就已经了如指掌了。Queue 是先进先出,Stack 是先进后出,或者说后进先出。它们的基本操作也都类似 ArrayList 的那些接口,下面我们来简单说说它们的特殊接口:


清单 10. Queue 示例
				 
 var q=new dojox.collections.Queue(["foo","bar","test","bull"]); 
 q.enqueue("bull"); 
 t.assertEqual("bull", q.toArray().pop()); 

 var q=new dojox.collections.Queue(["foo","bar","test","bull"]); 
 t.assertEqual("foo", q.dequeue()); 
 t.assertEqual("bar,test,bull", q.toArray().join(",")); 

“enqueue”表示入栈,“dequeue”表示出栈,可见 Queue 是先进先出的。如果仅仅想取值,请用“peek”方法。


清单 11. Stack 示例
				 
 var s=new dojox.collections.Stack(["foo","bar","test","bull"]); 
 t.assertEqual("bull", s.pop()); 
 t.assertEqual("test", s.pop()); 

 var s=new dojox.collections.Stack(["foo","bar","test","bull"]); 
 s.push("bug"); 
 t.assertEqual("bug", s.peek()); 

“push”表示入栈,“pop”表示出栈,“s.peek()”出的值为“bug”表示 Stack 为后进先出的线性结构。如果仅仅想取值,也请用“peek”。

Set

相信我们对 Set 这个对象已经不陌生了,它的最大的特点就是元素的唯一性。同样,Dojo 中的 Set 也是如此,但是 Dojo 中的 Set 的主要用法不是构建 Set 对象,而是 Set 本身的一些方法:


清单 12. Set 的方法
				 
 var dxcs=dojox.collections.Set; 

 var a = ["apple","bear","candy","donut","epiphite","frank"]; 
 var b = ["bear","epiphite","google","happy","joy"]; 


 var union=dxcs.union(a,b); 
 t.assertEqual("apple,bear,candy,donut,epiphite,frank,google,happy,joy", 
                                             union.toArray().join(',')); 
                                             
 var itsn=dxcs.intersection(a,b); 
 t.assertEqual("bear,epiphite", itsn.toArray().join(",")); 
 t.assertEqual("bear", dxcs.intersection(["bear","apple"], ["bear"])); 


 var d=dxcs.difference(a,b); 
 t.assertEqual("apple,candy,donut,frank",d.toArray().join(',')); 


 t.assertFalse(dxcs.isSubSet(a,["bear","candy"])); 
 t.assertTrue(dxcs.isSubSet(["bear","candy"],a)); 


 t.assertTrue(dxcs.isSuperSet(a,["bear","candy"])); 
 t.assertFalse(dxcs.isSuperSet(["bear","candy"],a)); 

代码可能有点多,我们来一一结介绍:

  1. 注意 dxcs 是指代的 Dojo 的 Set 类 -- “dojox.collections.Set”。关注“a”和“b”两个集合。
  2. “union”表示联合,但是 Set 的联合方法会去除重复元素。
  3. “intersection”是做交叉,选出两个集合里面具有的元素,然后组成集合。
  4. “difference”是取得集合“a”中存在但集合“b”中不存在的元素。
  5. “isSubSet”和“isSuperSet”分别指“是否为子集”和“是否为超集”。

Dictionary

之前其实我们已经简单了解过了,它的实类似于“java.util.Dictionary”。它的基本操作也是与 ArrayList 类似,但不同的是它是 map 结构,有两个属性:“key”和“value”,不同于简单线性结构(如:ArrayList)。我们先来看看以下实例:


清单 13. Dictionary 的方法
				 
 var d=new dojox.collections.Dictionary(); 

 d.add("foo","bar"); 
 d.add("baz","fab"); 
 d.add("buck","shot"); 
 d.add("apple","orange"); 

 t.assertTrue(d.containsKey("buck")); 

 t.assertTrue(d.containsValue("shot")); 

 t.assertEqual("foo,baz,buck,apple", d.getKeyList().join(",")); 

 t.assertEqual("bar,fab,shot,orange", d.getValueList().join(",")); 

 d.remove("baz"); 
 t.assertEqual(3, d.count); 
 t.assertEqual(undefined, d.item("baz")); 

可以看出,这里添加元素还是用“add”,但是不再是添加值,而是添加“ 键 - 值 ”对。它的“contains”方法也可分为“containsKey”和“containsValue”两种。同样,也有“getKeyList”和“getValueList”两种。当调用“remove”方法删除元素以后,Dictionary 的长度也会变化,并且删除的值变为“undefined”。

SortedList

SortedList 和 Dictionary 有很相似性,不同的是,该线性结构里的元素是排好序(基于键“key”排序)存储的。


清单 14. SortedList 的方法
				 
 var sl=new dojox.collections.SortedList(); 

 sl.add("foo","bar"); 
 sl.add("baz","fab"); 
 sl.add("buck","shot"); 
 sl.add("apple","orange"); 

 t.assertEqual("shot", sl.getByIndex(2)); 

 t.assertEqual("apple", sl.getKey(0)); 

 t.assertEqual(0, sl.indexOfKey("apple")); 

 t.assertEqual(3, sl.indexOfValue("bar")); 

 sl.setByIndex(0, "bar"); 
 t.assertEqual("bar", sl.getByIndex(0)); 

SortedList 的方法:“containsKey”,“containsValue”,“getKeyList”,“getValueList”和“remove”等等这里就不一一列举了。我们来看一下它特有的方法:

  1. 注意到,虽然它是按“foo”,“baz”,“buck”,“apple”的顺序添加,但是它的内部顺序为:“apple”,“baz”,“buck”,“foo”,所以 value 的顺序应为:“orange”,“fab”,“shot”,“bar”。基于这种机制,我们就能了解它的一些接口的返回值。
  2. “getByIndex(2)”应该是返回第三个元素的 value,所以为“shot”。
  3. “getKey(0)”自然是第一个元素的 key,所以为“apple”。
  4. “indexOfKey("apple")”返回元素“apple”的 index,为 0;“indexOfValue”返回 value 元素“bar”的位置,为第四个元素,即 index 为 3。
  5. “setByIndex”和“getByIndex”是根据位置设置值和取值。

可以看出,SortedList 的接口是很全面的,建议大家在项目中多使用。

结束语

这篇文章介绍了 Dojo 中关于 Collections 集合对象的一些特性,从 collection 工具包的基础出发,依次介绍了 ArrayList、BinaryTree、Queue、Stack、Set、Dictionary 以及 SortedList 等,介绍了它们的基本接口,高级接口和一些特殊接口。同时,也阐述了这些不同集合对象之间的相同点和不同点。本文主要是基于实际的代码示例来说明这些集合对象的用法,简明直观,推荐大家在日常开发中多参考。

分享到:
评论

相关推荐

    Dojo工具使用说明

    Dojo 是一个强大的JavaScript工具包,专为构建富互联网应用程序(RIA)而设计。它提供了丰富的功能,包括UI组件、事件处理、动画效果、Ajax通信、数据存储等。以下是对Dojo工具包及其主要功能的详细说明: 1. **...

    dojo api 中文版

    * dojo.colors:颜色工具包。 * dojo.data:Dojo 的统一数据访问接口,支持读取 XML、JSON 等不同格式的数据文件。 * dojo.fx:基本动画效果库。 * dojo.regexp:正则表达式处理函数库。 * dijit.forms:表单控件...

    DOJO API 中文参考手册,附加注解实例(精心重新排版DOC文档)

    Dojo API 中文参考手册包含了丰富的Dojo框架的详细信息,尤其强调了Dojo的包系统和组件(Widget)体系。Dojo是一个JavaScript库,它提供了大量的功能,以支持Web应用的开发,尤其是在Ajax和用户界面(UI)设计方面。...

    DOJO—API—中文参考手册

    9. **dojo.colors**:提供颜色相关的工具包。 10. **dojo.data**:提供统一的数据访问接口,支持从不同格式的数据文件(如XML、JSON)中读取数据。 11. **dojo.fx**:提供基本的动画效果。 12. **dojo.regexp**:...

    dojo API pdf

    - **dojo.colors**:颜色处理工具包。 - **dojo.data**:统一数据访问接口,支持读取XML、JSON等多种格式数据。 - **dojo.fx**:基本动画效果库。 - **dojo.regexp**:正则表达式处理函数库。 - **dijit.forms**:...

    dojo api 1.0 中文文档

    - **dojo.colors**:颜色工具包。 - **dojo.data**:提供统一的数据访问接口,支持 XML、JSON 等格式的数据文件读取。 - **dojo.fx**:基本动画效果库。 - **dojo.regexp**:正则表达式处理函数库。 - **dijit.forms...

    DOJO_API_中文参考手册 附加注释实例

    Dojo API中文参考手册是一个面向初学者的指导性文件,它详细介绍了Dojo框架的体系结构、常用包及功能,并通过附加注释实例帮助开发者理解和使用Dojo。以下是根据给定内容整理的知识点: 1. Dojo体系架构分层: - ...

    dojo技术入门ysk

    Dojo是一个开源的JavaScript工具包,主要用于构建富互联网应用(Rich Internet Applications, RIA)。它具有轻量级且易于安装的特点,在Web 2.0时代,随着Ajax技术的发展而兴起。Dojo提供了一系列丰富的功能,包括但...

    DOJO API 中文参考手册,附加注解实例

    - **dojo.colors**:颜色处理工具包。 - **dojo.data**:统一的数据访问接口,支持读取XML、JSON等多种格式的数据。 - **dojo.fx**:动画效果库,提供基本的动画功能。 - **dojo.regexp**:正则表达式处理库。...

    dojo api最好资料

    包系统的上一层是语言库,包含了多种语言工具API,类似于Java的`util`包。这些工具API能够帮助开发者处理常见的编程任务,比如字符串操作、日期处理等。 ##### 环境相关包 这一层主要处理跨浏览器兼容性问题。由于...

    dojo中文文档分析与介绍

    Dojo的目标是成为统一的工具包,整合了多种功能(如nWidgets、Burstlib等),并旨在解决DHTML应用中常见的问题。与其他框架相比,Dojo的优势在于其广泛的社区支持和强大的功能集。 ### Dojo框架的核心模块与功能 ...

    三大框架整合包

    在压缩包中,有多个Struts2相关的文件,如struts2-dojo-plugin-2.1.8.jar(Struts2的Dojo插件,用于增强前端展示效果),xwork-core-2.1.6.jar(XWork是Struts2的基础,负责处理Action和业务逻辑),struts2-core-...

    struts2 jar包

    `commons-collections-3.2.jar`是Apache Commons Collections库,包含了一系列集合操作和实用工具类,如列表、映射、堆栈等,为Struts2提供了丰富的数据结构和算法支持。 `spring-beans-2.5.3.jar`和`spring-...

    struts2资源包

    其中,`struts2-core.jar`提供了MVC架构的支持,`struts2-convention-plugin.jar`实现了自动映射和默认配置,`struts2-dojo-plugin.jar`提供了与Dojo JavaScript库的集成,还有其他如JSON、Freemarker等插件,用于...

    SSH整合的JAR包

    - commons-collections-3.2.jar:Apache Commons Collections,提供了一组实用的集合操作工具类。 这些JAR包是SSH整合项目的基础,它们共同构成了一个完整的开发环境,支持开发者快速构建企业级应用。在实际项目中...

    struts全部的包

    2. **依赖库**:Struts框架通常依赖于其他库,如Commons Logging、Commons BeanUtils、Commons Collections、Commons Lang等Apache Commons项目,这些库提供了日志、数据绑定、集合操作和通用工具方法等功能。...

    struts2导入的包

    2. **Plugins**: Struts2有很多插件,如`struts2-convention-plugin.jar`用于自动配置,`struts2-json-plugin.jar`支持JSON响应,`struts2-dojo-plugin.jar`提供Dojo工具集,等等。这些插件扩展了Struts2的功能,使...

    struts2要用到的所有jar包全集

    Dojo是一个强大的JavaScript工具集,用于创建交互式的用户界面,包括数据网格、图表和表单组件。通过这个插件,开发者可以方便地在Struts2应用中利用Dojo的功能。 2. **xwork-core-2.2.1.jar**:XWork是Struts2的...

Global site tag (gtag.js) - Google Analytics