一直觉得AS3关于集合的API太少,可以说是没有,仅仅提供了Object、Array、Vector等,这些可以满足日常的编程需求,不过,我觉得有点不足,于是就稍稍封装了一下这块。
ArrayList实现了IList全部接口,其具体实现代码如下:
package tunie.struct.group { import tunie.struct.EqualsUtil; import tunie.struct.error.ErrorDesc; /** * Tunie * Oct 8, 2015 3:46:22 PM * <b>List主要功能如下</b> * <li>列表 */ public class ArrayList extends Group implements IList , IGroup { protected var _list:Array; public function ArrayList() { _list = []; } //pass public function get size():int { return _list.length; } //pass public function add(value:*):void { _list.push(value); } //pass public function addList(list:IList):void { if(list == null) return ; if(list is ArrayList) { addArr((list as ArrayList).content); } else { for(var i:int = 0; i < list.size ;i ++) { add(list.obtain(i)); } } } //pass public function addArr(list:Array):void { if(list == null) return ; for(var i:int = 0; i < list.length ; i++) { add(list[i]); } } //pass public function alter(value:*, toValue:*):void { var indexList:IList = obtainIndexList(value); if(indexList == null) return; for(var i:int = 0; i < indexList.size; i++) { alterAt(indexList.obtain(i) , toValue); } } //pass public function alterAt(index:int, value:*):* { index = checkIndex(index); var oriValue:* = obtain(index); _list[index] = value; return oriValue; } //pass public function alterList(startIndex:int, endIndex:int, list:IList):IList { var tempList:IList = removeRangeList(startIndex , endIndex); insertList(list , startIndex); return tempList; } //pass public function clearRepeat():IList { if(isEmpty) return null; var indexList:IList = new ArrayList(); for(var i:int = 0 ; i < size ; i++) { if(indexList.contain(i)) continue; var tempList:IList = obtainIndexList(obtain(i)); tempList.removeAt(0); indexList.addList(tempList); } return removeIndexList(indexList); } //pass public function insert(value:*, index:int=0):void { index = checkIndex(index); _list.splice(index , 0 , value); } //pass public function insertList(list:IList, index:int=0):void { if(list == null) return; if(isEmpty || index >= size) addList(list); for(var i:int = list.size - 1; i >= 0 ; i--) { insert(list.obtain(i) , index); } } //pass public function obtain(index:int=0):* { index = checkIndex(index); return _list[index]; } //pass public function obtainIndex(value:*):int { if(isEmpty) return -1; for(var i:int = 0; i < size ; i++) { var tempValue:* = obtain(i); if(EqualsUtil.checkEquals(value , obtain(i))) return i; } return -1; } //pass public function obtainIndexList(value:*):IList { if(isEmpty) return null; var list:IList = new ArrayList(); for(var i:int = 0; i < size ; i++) { var tempValue:* = obtain(i); if(EqualsUtil.checkEquals(value , obtain(i))) { list.add(i); } } return list; } //pass public function remove(value:*):Boolean { if(isEmpty) return false; var indexList:IList = obtainIndexList(value); removeIndexList(indexList); return false; } //pass public function removeAt(index:int=0):* { if(isEmpty) return null; index = checkIndex(index); var oriValue:* = obtain(index); _list.splice(index , 1); return oriValue; } //pass public function removeIndexList(indexList:IList):IList { if(indexList.isEmpty) return null; var list:IList = new ArrayList(); for(var i:int = indexList.size - 1; i >= 0; i--) { list.add(removeAt(indexList.obtain(i))); } return list; } //pass public function removeList(list:IList):void { if(list == null) return ; var indexList:IList = new ArrayList(); for(var i:int = 0; i < list.size ; i++) { indexList.addList(obtainIndexList(list.obtain(i))); } removeIndexList(indexList); } //pass public function removeRangeList(startIndex:int, endIndex:int):IList { if(checkIndexRange(startIndex , endIndex)){ var arrList:Array = _list.splice(startIndex , endIndex - startIndex); var list:IList = new ArrayList(); list.addArr(arrList); return list; } return null; } //pass public function subList(startIndex:int, endIndex:int):IList { if(checkIndexRange(startIndex , endIndex)){ var arrList:Array = _list.slice(startIndex , endIndex); var list:IList = new ArrayList(); list.addArr(arrList); return list; } return null; } override public function clear():void { _list = []; } //pass override public function contain(value:*):Boolean { if(isEmpty) return false; var index:int = obtainIndex(value); return index >= 0; } //pass override public function get isEmpty():Boolean { return size == 0; } /** * 取得数组(ArrayList特有) * @return */ //pass public function get content():Array { return _list; } /** * 检测索引值 * @param value * @return */ //pass protected function checkIndex(value:int):int { if(isEmpty) value = 0; if(value >= size - 1) return size - 1; return value; } /** * 检测startIndex到endIndex范围,并返回取值是否合理 * @param startIndex * @param endIndex * @return */ //pass protected function checkIndexRange(startIndex:int , endIndex:int):Boolean { if(isEmpty) return false; if(startIndex >= endIndex) { ErrorDesc.throws("传入的参数列表有误,startIndex只能小于endIndex"); } if(startIndex >= size) { ErrorDesc.throws("传入的参数列表有误,startIndex不可超出列表最大索引"); } if(endIndex > size) { ErrorDesc.throws("传入的参数列表有误,endIndex不可超出列表最大索引"); } return true; } } }
代码注释很清楚,也很简洁,若有不是很明白的地方,可以回复提出。下面贴出依赖的类
IGroup
package tunie.struct.group { /** * Tunie * Oct 8, 2015 3:51:26 PM * <b>IGroup主要功能如下</b> * <li>组群 */ public interface IGroup { /** * 清空 */ function clear():void; /** * 返回是否为空,空为true,不为空为false * @return */ function get isEmpty():Boolean; /** * 返回是否包含value值,包含为true,不包含为false * @param value * @return */ function contain(value:*):Boolean; } }
Group
package tunie.struct.group { import tunie.struct.error.ErrorDesc; /** * Tunie * Oct 8, 2015 4:00:29 PM * <b>Group主要功能如下</b> * <li>1. */ public class Group implements IGroup { public function Group() { clear(); } public function clear():void { ErrorDesc.throwsNoRewrite(this , "clear"); } public function get isEmpty():Boolean { ErrorDesc.throwsNoRewrite(this , "isEmpty"); return false; } public function contain(value:*):Boolean { ErrorDesc.throwsNoRewrite(this , "contain"); return false; } } }
ErrorDesc
package tunie.struct.error { /** * May 10, 2015 * author: Tunie * function desc: * 抛出异常描述 */ public class ErrorDesc { /** 抛出没有重写父类方法 */ public static function throwsNoRewrite(target:* , fnName:String = ""):void { throws(target + "没有重写方法" + fnName); } /** 抛出无法实例化异常 */ public static function throwsCanotInstance(target:*):void { throws(target + "无法直接实例化"); } /** 抛出指定描述的异常 */ public static function throws(desc:String , params:Object = null , id:* = 0):void { throw new MyError(desc , params , id); } } }
MyError
package tunie.struct.error { /** * May 10, 2015 * author: Tunie * function desc: * */ public class MyError extends Error { private var _params:Object; public function MyError(message:*="",params:Object = null , id:*=0) { this.params = params; super(message, id); } public function get params():Object { return _params; } public function set params(value:Object):void { _params = value; } } }
IList
package tunie.struct.group { /** * Tunie * Oct 8, 2015 4:35:03 PM * <b>IList主要功能如下</b> * <li>列表 */ public interface IList extends IGroup { /** * 列表长度 * @return */ function get size():int; /** * 在尾部新增一个元素 * @param value */ function add(value:*):void; /** * 在尾部新增一个列表 * @param list */ function addList(list:IList):void; /** * 添加一个数组到列表,数组中的每个元素做为列表中的一项 * @param list */ function addArr(list:Array):void; /** * 往指定index插入索引 * @param value 值 * @param index 索引 */ function insert(value:* , index:int = 0):void; /** * 在指定index插入列表, * @param list * @param index */ function insertList(list:IList , index:int = 0):void; /** * 移除列表中指定值(全部) * @param value */ function remove(value:*):Boolean; /** * 移除指定index的值 * @param index * @return 被移除的值 */ function removeAt(index:int = 0):*; /** * 移除列表中的多个指定值 * @param startIndex * @param endIndex * @return 被移除的子列表 */ function removeList(list:IList):void ; /** * 移除列表中的指定索引值 * @param list * @return */ function removeIndexList(indexList:IList):IList; /** * 移除从startIndex到endIndex的值,不包含endIndex * @param startIndex * @param endIndex * @return 被移除的子列表 */ function removeRangeList(startIndex:int , endIndex:int):IList ; /** * 修改指定值 * @param value */ function alter(value:* , toValue:*):void; /** * 修改指定index的值 * @param index * @param value * @return */ function alterAt(index:int , value:*):*; /** * 修改从startIndex到endIndex的值为指定的list,不包含endIndex * @param startIndex * @param endIndex * @param list * @return 被修改的子列表 */ function alterList(startIndex:int , endIndex:int , list:IList):IList; /** * 获取索引index的值 * @param index * @return */ function obtain(index:int = 0):*; /** * 获取值的首个索引 * @param value * @return */ function obtainIndex(value:*):int; /** * 获取值在列表中的所有索引 * @param value * @return */ function obtainIndexList(value:*):IList; /** * 取得从startIndex到endIndex的子列表,不包含endIndex * @param startIndex 开始位置 * @param endIndex 结束位置 * @return */ function subList(startIndex:int , endIndex:int):IList; /** * 清除重复的项 * @return 被清除的项列表 */ function clearRepeat():IList; } }
IEquals
package tunie.struct { /** * Tunie * Oct 9, 2015 9:34:10 AM * <b>IEquals主要功能如下</b> * <li>是否相同 */ public interface IEquals { /** * 判断是否相同 * @param value * @return */ function equals(value:*):Boolean; } }
EqualsUtil
package tunie.struct { /** * Tunie * Oct 9, 2015 9:37:01 AM * <b>EqualsUtil主要功能如下</b> * <li>判断是否相同工具 */ public class EqualsUtil { /** * 判断是否相同 * @param target * @param toTarget * @return */ public static function checkEquals(target:* , toTarget:*):Boolean { //当两者都为null时,返回true if(target == null) { return toTarget == null; } //若为IEquals实例,调用equals接口 if(target is IEquals) { return (target as IEquals).equals(toTarget); } else { return target == toTarget; } } } }