UNPKG

jcollections

Version:

A Powerful Collections Framework in JavaScript

1,545 lines (1,381 loc) 37.5 kB
(function(global, undefined) { "use strict"; /** *继承 */ Function.prototype.inherits = function(Parent) { if (typeof Parent !== 'function') { throw TypeError("Parent incorrect"); } this.prototype = new Parent(); this.prototype.constructor = this; return this; }; /** *集合标识类型 */ function Collection(){}; /** *size(); *返回集合元素个数 */ Collection.prototype.size = function() { return this.__mSize__(); } /** *isEmpty(); *集合是否为空 */ Collection.prototype.isEmpty = function() { return this.size() === 0; } /** *用于自定义equals函数,例如: *defineEquals(function(elem0, elem1) { * return elem0.name === elem1.name; *});两个元素的name属性相同则认为是同一个对象 */ Collection.prototype.defineEquals = function(equalsFn) { this.__equals__ = equalsFn; }; //默认的equals函数 Collection.prototype.__equals__ = function(elem0, elem1) { return elem0 === elem1; }; /* *有序集合标识类型 */ var List = function(){}.inherits(Collection);//继承了Collection //检查索引值的范围 List.prototype.__rangeCheck__ = function(index, canBeSize) { if (typeof index !== 'number') { throw Error('index incorrect'); } if (index === 0 && this.size() === 0) return; if (index < 0 || (canBeSize ? index > this.size() : index >= this.size())) { throw Error('index out of bounds: index:' + index + ', size:' + this.size()); } }; /** *new ArrayList(); || new ArrayList(Array); *构造一个新的ArrayList实例 */ var ArrayList = function(ary) { if (!(this instanceof ArrayList)) { return new ArrayList(ary); } this.__data__ = (ary instanceof Array) ? ary : []; }.inherits(List);//ArrayList继承了List /** *ArrayList.create(); || ArrayList.create(Array); *静态方法,创建一个ArrayList实例 */ ArrayList.create = function(ary) { return new ArrayList(ary); }; //返回list元素个数 ArrayList.prototype.__mSize__ = function() { return this.__data__.length; }; /** *add(elem0[, elem1[, elem2[,...]]]); *添加一到多个元素到list尾部 */ ArrayList.prototype.add = function() { this.__data__ = this.__data__.concat(Array.prototype.slice.call(arguments)); }; /** *insert(index, elem0[, elem1[, elem2[,...]]]); *在指定位置插入一到多个元素 */ ArrayList.prototype.insert = function() { var args = arguments, index = args[0], elems; this.__rangeCheck__(index, true); elems = Array.prototype.slice.call(arguments); elems.splice(0, 1); Array.prototype.splice.apply(this.__data__, [parseInt(index), 0].concat(elems)); }; /** *set(index, elem); *将指定位置的元素替换成新元素 */ ArrayList.prototype.set = function(index, elem) { this.__rangeCheck__(index); var data = this.__data__, oldElem = data[index]; data[index] = elem; return oldElem; }; /** *toArray() *返回一个含有所有元素的数组对象 */ ArrayList.prototype.toArray = function() { return this.__data__.slice(0); }; /** *get(index); *返回指定位置所对应的元素 */ ArrayList.prototype.get = function(index) { this.__rangeCheck__(index); return this.__data__[index]; }; /** *addAll(collection); *添加一个集合对象到list尾部 */ ArrayList.prototype.addAll = function(collection) { if (!(collection instanceof Collection)) { throw Error('not a Collection instance'); } if (!collection.isEmpty()) { this.__data__ = this.__data__.concat(collection.toArray()); } }; /** *insertAll(index, collection); *在指定位置插入一个集合对象 */ ArrayList.prototype.insertAll = function(index, collection) { this.__rangeCheck__(index, true); if (!(collection instanceof Collection)) { throw Error('not a Collection instance'); } if (!collection.isEmpty()) { Array.prototype.splice.apply(this.__data__, [parseInt(index), 0].concat(collection.toArray())); } }; /** *clear(); *清空集合中的元素 */ ArrayList.prototype.clear = function() { this.__data__.length = 0; }; /** *removeAt(index); *移除指定位置的元素 */ ArrayList.prototype.removeAt = function(index) { this.__rangeCheck__(index); return this.__data__.splice(index, 1)[0]; }; /** *removeElement(elem); *移除指定元素 */ ArrayList.prototype.removeElement = function(elem) { var data = this.__data__; for (var i = 0, len = data.length; i < len; i++) { if (this.__equals__(data[i], elem)) { data.splice(i, 1); return true; } } return false; }; /** *removeRange(fromIndex, toIndex); *移除指定开始位置到结束位置的所有元素--包括开始位置,但不包括结束位置 */ ArrayList.prototype.removeRange = function(fromIndex, toIndex) { this.__rangeCheck__(fromIndex); this.__rangeCheck__(toIndex); if (fromIndex > toIndex) { throw Error('fromIndex > toIndex'); } return this.__data__.splice(fromIndex, toIndex - fromIndex); }; /** *indexOf(elem); *返回指定元素第一次出现的位置 */ ArrayList.prototype.indexOf = function(elem) { var data = this.__data__; for (var i = 0, len = data.length; i < len; i++) { if (this.__equals__(data[i], elem)) { return i; } } return -1; }; /** *lastIndexOf(elem); *返回指定元素最后一次出现的位置 */ ArrayList.prototype.lastIndexOf = function(elem) { var data = this.__data__; for (var i = data.length - 1; i >= 0; i--) { if (this.__equals__(data[i], elem)) { return i; } } return -1; }; /** *contains(elem); *集合是否含有指定元素 */ ArrayList.prototype.contains = function(elem) { return this.indexOf(elem) !== -1; }; /** *toString(); *返回一个含有所有元素的字符串 */ ArrayList.prototype.toString = function() { return '['+ this.__data__.join(',') + ']'; }; /** *iterator(); *iterator(index);从指定位置开始迭代 *获取一个迭代器 */ ArrayList.prototype.iterator = function(index) { if ((index = index || 0) !== 0) { this.__rangeCheck__(index); } var ArrayListIterator = function(arrayList) { var cursor = index, lastCursor = index - 1, data = arrayList.__data__, next; this.hasNext = function() { return cursor < arrayList.size(); }; this.next = function() { next = data[cursor]; lastCursor = cursor++; return next; }; this.set = function(elem) { if (lastCursor === -1) { throw Error('illegal state'); } arrayList.set(lastCursor, elem); }; this.remove = function() { if (lastCursor === -1) { throw Error('illegal state'); } arrayList.removeAt(lastCursor); cursor--; lastCursor = -1; }; }; return new ArrayListIterator(this); }; /** *new LinkedList(); || new LinkedList(Collection); *构造一个新的LinkedList实例 */ var LinkedList = function(collection) { if (!(this instanceof LinkedList)) { return new LinkedList(collection); } this.__size__ = 0; this.__header__ = {}; this.__header__.next = this.__header__.previous = this.__header__; if (collection instanceof Collection) { this.addAll(collection); } }.inherits(List);//LinkedList继承了List /** *LinkedList.create(); || LinkedList.create(Collection); *静态方法,创建一个LinkedList实例 */ LinkedList.create = function(collection) { return new LinkedList(collection); }; //返回链表个数 LinkedList.prototype.__mSize__ = function() { return this.__size__; }; //在指定节点前添加一个新的节点元素 LinkedList.prototype.__addBefore__ = function(elem, entry) { var newEntry = {elem:elem, next:entry, previous:entry.previous}; newEntry.previous.next = newEntry; newEntry.next.previous = newEntry; this.__size__++; }; //获取指定位置的节点 LinkedList.prototype.__getEntry__ = function(index) { var size = this.__size__, entry = this.__header__; if (index < (size >> 1)) {//二分法 for (var i = 0; i <= index; i++) {//从前往后 entry = entry.next; } } else { for (var i = size; i > index; i--) {//从后往前 entry = entry.previous; } } return entry; }; //移除指定的结点 LinkedList.prototype.__removeEntry__ = function(entry) { if (entry === this.__header__) { throw Error('no such element in this list'); } var retVal = entry.elem; entry.next.previous = entry.previous; entry.previous.next = entry.next; entry.next = entry.previous = null entry.elem = null; this.__size__--; return retVal; }; /** *add(elem0[, elem1[, elem2[,...]]]); *添加一个到多个元素节点到链表尾部 */ LinkedList.prototype.add = function() { var args = arguments; for (var i = 0, len = args.length; i < len; i++) { this.__addBefore__(args[i], this.__header__); } }; /** *insert(index, elem0[, elem1[, elem2[,...]]]); *在指定位置插入一个到多个新的节点元素 */ LinkedList.prototype.insert = function() { var args = arguments, index = args[0], elems; this.__rangeCheck__(index, true); elems = Array.prototype.slice.call(arguments); elems.splice(0, 1); for (var i = 0, len = elems.length; i < len; i++) { this.__addBefore__(elems[i], (index === this.__size__ ? this.__header__ : this.__getEntry__(index))); index++; } }; /** *addFirst(elem); *在链表头部添加一个新的节点元素 */ LinkedList.prototype.addFirst = function(elem) { this.__addBefore__(elem, this.__header__.next); }; /** *addLast(elem); *在链表尾部追加一个新的节点元素 */ LinkedList.prototype.addLast = function(elem) { this.__addBefore__(elem, this.__header__); }; /** *toString(); *返回一个含有所有元素的字符串 */ LinkedList.prototype.toString = function() { return '[' + this.toArray().join(',') + ']'; }; /** *toArray(); *返回一个含有所有元素的数组 */ LinkedList.prototype.toArray = function() { var result = [], header = this.__header__; for (var entry = header.next; entry !== header; entry = entry.next) { result.push(entry.elem); } return result; }; /** *addAll(collection); *添加一个集合对象到链表尾部 */ LinkedList.prototype.addAll = function (collection) { if (!(collection instanceof Collection)) { throw Error('not a Collection instance'); } if (!collection.isEmpty()) { this.insertAll(this.__size__, collection); } }; /** *insertAll(index, collection); *在指定位置插入一个集合对象 */ LinkedList.prototype.insertAll = function (index, collection) { this.__rangeCheck__(index, true); if (!(collection instanceof Collection)) { throw Error('not a Collection instance'); } if (collection.isEmpty()) return; var successor = (index === this.__size__ ? this.__header__ : this.__getEntry__(index)), predecessor = successor.previous, data = collection.toArray(); for (var i = 0, len = data.length; i < len; i++) { var newEntry = {elem:data[i], next:successor, previous:predecessor}; predecessor.next = newEntry; predecessor = newEntry; } successor.previous = predecessor; this.__size__ += data.length; }; /** *clear(); *清空链表 */ LinkedList.prototype.clear = function() { var header = this.__header__, entry = header.next, next; while (entry !== header) { next = entry.next; entry.next = entry.previous = null; entry.elem = null; entry = next; } header.next = header.previous = header; this.__size__ = 0; }; /** *indexOf(elem); *返回指定节点元素第一次出现的位置 */ LinkedList.prototype.indexOf = function(elem) { var index = 0, header = this.__header__; for (var entry = header.next; entry !== header; entry = entry.next) { if (this.__equals__(entry.elem, elem)) { return index; } index++; } return -1; }; /** *lastIndexOf(elem); *返回指定节点元素最后一次出现的位置 */ LinkedList.prototype.lastIndexOf = function(elem) { var index = this.__size__, header = this.__header__; for (var entry = header.previous; entry !== header; entry = entry.previous) { index--; if (this.__equals__(entry.elem, elem)) { return index; } } return -1; }; /** *contains(elem); *链表中是否含有指定结点元素 */ LinkedList.prototype.contains = function(elem) { return this.indexOf(elem) !== -1; }; /** *getFirst(); *获取链表中第一个结点元素 */ LinkedList.prototype.getFirst = function() { if (this.__size__ === 0) { throw Error('no element in this list'); } return this.__header__.next.elem; }; /** *getLast(); *获取链表中最后一个结点元素 */ LinkedList.prototype.getLast = function() { if (this.__size__ === 0) { throw Error('no element in this list'); } return this.__header__.previous.elem; }; /** *get(index); *获取指定位置的结点元素 */ LinkedList.prototype.get = function(index) { this.__rangeCheck__(index); return this.__getEntry__(index).elem; }; /** *set(index); *将指定位置的结点替换成新的结点元素 */ LinkedList.prototype.set = function(index, elem) { this.__rangeCheck__(index); var entry = this.__getEntry__(index), oldElem = entry.elem; entry.elem = elem; return oldElem; }; /** *removeFirst(); *移除链表第一个元素结点 */ LinkedList.prototype.removeFirst = function() { return this.__removeEntry__(this.__header__.next); }; /** *removeLast(); *移除链表最后一个元素结点 */ LinkedList.prototype.removeLast = function() { return this.__removeEntry__(this.__header__.previous); }; /** *removeAt(index); *移除指定位置的元素结点 */ LinkedList.prototype.removeAt = function(index) { this.__rangeCheck__(index); return this.__removeEntry__(this.__getEntry__(index)); }; /** *removeElement(elem); *从链表中移除指定元素结点 */ LinkedList.prototype.removeElement = function(elem) { var header = this.__header__; for (var entry = header.next; entry !== header; entry = entry.next) { if (this.__equals__(entry.elem, elem)) { this.__removeEntry__(entry); return true; } } return false; }; /** *removeFirstOccurrence(elem); *移除指定元素第一次出现的结点 */ LinkedList.prototype.removeFirstOccurrence = function(elem) { this.removeElement(elem); }; /** *removeLastOccurrence(elem); *移除指定元素最后一次出现的结点 */ LinkedList.prototype.removeLastOccurrence = function(elem) { var header = this.__header__; for (var entry = header.previous; entry !== header; entry = entry.previous) { if (this.__equals__(entry.elem, elem)) { this.__removeEntry__(entry); return true; } } return false; }; /** *iterator(); *iterator(index);从指定位置开始迭代 *获取链表迭代器 */ LinkedList.prototype.iterator = function(index) { var index = index || 0, size = this.__size__, header = this.__header__; this.__rangeCheck__(index, true); var LinkedListIterator = function(linkedList) { var last = header, next, nextIndex; if (index < (size >> 1)) { next = header.next; for (nextIndex = 0; nextIndex < index; nextIndex++) { next = next.next; } } else { next = header; for (nextIndex = size; nextIndex > index; nextIndex--) { next = next.previous; } } this.hasNext = function() { return nextIndex < size; }; this.next = function() { if (nextIndex === size) { throw Error('no such element in this list'); } last = next; next = next.next; nextIndex++; return last.elem; }; this.hasPrevious = function() { return nextIndex !== 0; }; this.previous = function() { if (nextIndex === 0) { throw Error('no such element in this list'); } last = next = next.previous; nextIndex--; return last.elem; }; this.set = function(elem) { if (last === header) { throw Error('illegal state'); } last.elem = elem; }; this.remove = function() { linkedList.__removeEntry__(last); nextIndex--; size--; last = header; }; }; return new LinkedListIterator(this); }; //负责对象和内部键之间的相互转换 var KeyConvertor = { toInnerKey: function(outerValue) { if (typeof outerValue === 'object' && !outerValue.__hash__) { outerValue.__hash__ = collections.__hash__++; } return (typeof outerValue) + '@' + (outerValue.__hash__ || outerValue); }, fromInnerKey: function(innerKey) { var first = innerKey.indexOf('@'), type = innerKey.substring(0, first), value = innerKey.substring(first + 1); if (type === 'string') { return value; } else if (type === 'number') { return Number(value); } else if (type === 'boolean') { return Boolean(value); } else { return innerKey; } } }; /* *无序集合标识类型 */ var Set = function(){}.inherits(Collection);//继承了Collection /** *new HashSet(); || new HashSet(Collection); *构造一个新的HashSet实例 */ var HashSet = function(collection) { if (!(this instanceof HashSet)) { return new HashSet(collection); } this.__store__ = {}; this.__size__ = 0; if (collection instanceof Collection) { this.addAll(collection); } }.inherits(Set);//HashSet继承了Set /** *HashSet.create(); || HashSet.create(Collection); *静态方法,创建一个HashSet实例 */ HashSet.create = function(collection) { return new HashSet(collection); }; //返回set元素个数 HashSet.prototype.__mSize__ = function() { return this.__size__; }; //重写Collection的defineEquals函数 HashSet.prototype.defineEquals = function(equalsFn) { Collection.prototype.defineEquals.call(this, equalsFn); this.__overwriteEquals__ = true; }; /** *add(elem); *添加一个元素到set中 */ HashSet.prototype.add = function() { var args = arguments, store = this.__store__; for (var i = 0, len = args.length; i < len; i++) { var elem = args[i], isNew = !this.contains(elem); if (isNew) { var key = KeyConvertor.toInnerKey(elem); if (typeof elem === 'object') { store[key] = elem; } else { store[key] = 1; } this.__size__++; } } }; /** *addAll(collection); *添加一个集合对象到set中 */ HashSet.prototype.addAll = function(collection) { if (!(collection instanceof Collection)) { throw Error('not a Collection instance'); } if (collection.isEmpty()) return; var iter = collection.iterator(); while (iter.hasNext()) { this.add(iter.next()); } }; /** *remove(elem); *从set集合中移除一个指定元素 */ HashSet.prototype.remove = function(elem) { if (!this.contains(elem)) return; var store = this.__store__; if (typeof elem === 'object' && this.__overwriteEquals__) { for (var key in store) { if (this.__equals__(store[key], elem)) { delete store[key]; this.__size__--; return; } } } else { delete store[KeyConvertor.toInnerKey(elem)]; this.__size__--; } }; /** *toArray(); *返回含有set所有元素的数组 */ HashSet.prototype.toArray = function() { var result = [], store = this.__store__; for (var key in store) { if (key.indexOf('object@') === 0) { result.push(store[key]); } else { result.push(KeyConvertor.fromInnerKey(key)); } } return result; }; /** *toString(); *返回含有set所有元素的字符串 */ HashSet.prototype.toString = function() { return '[' + this.toArray().join(',') + ']'; }; /** *contains(elem); *set是否含有指定元素 */ HashSet.prototype.contains = function(elem) { var store = this.__store__; if (typeof elem === 'object' && this.__overwriteEquals__) { for (var key in store) { if (this.__equals__(store[key], elem)) { return true; } } return false; } return !!this.__store__[KeyConvertor.toInnerKey(elem)]; }; /** *clear(); *清空set */ HashSet.prototype.clear = function() { this.__store__ = {}; this.__size__ = 0; }; /** *iterator(); *获取迭代器 */ HashSet.prototype.iterator = function() { var set = this, store = this.__store__, keys = Object.keys(store), cursor = 0, lastCursor = - 1; var HashSetIterator = function() { this.hasNext = function() { return cursor < set.size(); }; this.next = function() { var key = keys[cursor], isObject = key.indexOf('object@') === 0, elem = isObject ? store[key] : KeyConvertor.fromInnerKey(key); lastCursor = cursor++; return elem; }; this.remove = function() { if (lastCursor === -1) { throw Error('illegal state'); } var key = keys[lastCursor], isObject = key.indexOf('object@') === 0, elem = isObject ? store[key] : KeyConvertor.fromInnerKey(key); set.remove(elem); keys.splice(lastCursor, 1); cursor--; lastCursor = -1; }; }; return new HashSetIterator(); }; /** *Map标识类型 */ function Map(){}; /** *size(); *返回map键值对个数 */ Map.prototype.size = function() { return this.__mSize__(); }; /** *isEmpty(); *map是否为空 */ Map.prototype.isEmpty = function() { return this.size() === 0; }; /** *new HashMap(); || new HashMap(Map); *构造一个新的HashMap实例 */ var HashMap = function(map) { if (!(this instanceof HashMap)) { return new HashMap(map); } this.__store__ = {}; this.__xkey__ = {};//object key mapping. this.__size__ = 0; if (map instanceof Map) { this.putAll(map); } }.inherits(Map);//HashMap继承了Map /** *HashMap.create(); || HashMap.create(Map); *静态方法,创建一个HashMap实例 */ HashMap.create = function(map) { return new HashMap(map); }; //返回键值对个数 HashMap.prototype.__mSize__ = function() { return this.__size__; }; /** *put(key, value); *添加新的键值对 */ HashMap.prototype.put = function(key, value) { var isNew = !this.containsKey(key), innerKey = KeyConvertor.toInnerKey(key); this.__store__[innerKey] = value; if (isNew) { this.__size__++; if (typeof key === 'object') { this.__xkey__[innerKey] = key;//{hash:real_key} } } }; /** *putAll(map); *将指定map的数据合并到本实例中 */ HashMap.prototype.putAll = function(map) { if (!(map instanceof Map)) { throw Error('not a Map instance'); } if (map.isEmpty()) return; var keySet = map.keySet(), iter = keySet.iterator(), key; while (iter.hasNext()) { key = iter.next(); this.put(key, map.get(key)); } }; /** *get(key); *根据指定的key获取对应的value */ HashMap.prototype.get = function(key) { return this.__store__[KeyConvertor.toInnerKey(key)]; }; /** *remove(key); *移除指定key对应的键值对 */ HashMap.prototype.remove = function(key) { if (this.containsKey(key)) { var innerKey = KeyConvertor.toInnerKey(key), store = this.__store__, value = store[innerKey]; delete store[innerKey]; this.__size__--; if (typeof key === 'object') { delete this.__xkey__[innerKey]; } return value; } return null; }; /** *clear(); *清空map */ HashMap.prototype.clear = function(key) { this.__store__ = {}; this.__xkey__ = {}; this.__size__ = 0; }; /** *containsKey(key); *map中是否含有指定的key */ HashMap.prototype.containsKey = function(key) { return !!this.__store__[KeyConvertor.toInnerKey(key)]; }; /** *containsValue(value); *map中是否含有指定的value */ HashMap.prototype.containsValue = function(value) { var store = this.__store__; for (var key in store) { if (store[key] === value) { return true; } } return false; }; /** *keySet(); *返回所有键组成的set集合 */ HashMap.prototype.keySet = function() { var set = new HashSet(); for (var key in this.__store__) { if (key.indexOf('object@') !== 0) { set.add(KeyConvertor.fromInnerKey(key)); } else { set.add(this.__xkey__[key]); } } return set; }; /** *entrySet(); *返回所有键值对组成的set集合 */ HashMap.prototype.entrySet = function() { var map = this, set = new HashSet(); var MapEntry = function(key, value) { this.__key__ = key; this.__value__ = value; this.getKey = function() { return this.__key__; }; this.getValue = function() { return this.__value__; }; this.set = function(value) { this.__value__ = value; map.put(this.__key__, value); }; this.toString = function() { return this.__key__ + '=' + this.__value__; }; }; for (var key in this.__store__) { var realKey; if (key.indexOf('object@') !== 0) { realKey = KeyConvertor.fromInnerKey(key); } else { realKey = this.__xkey__[key]; } set.add(new MapEntry(realKey, this.__store__[key])); } return set; }; /** *toString(); *返回含有map所有键值对的字符串 */ HashMap.prototype.toString = function() { var result = [], store = this.__store__; for (var key in store) { if (key.indexOf('object@') !== 0) { result.push(KeyConvertor.fromInnerKey(key) + '=' + store[key]); } else { result.push(this.__xkey__[key] + '=' + store[key]); } } return '{' + result.join(',') + '}'; }; /** *values(); *返回含有map所有值的字符串 */ HashMap.prototype.values = function() { var result = [], store = this.__store__;; for (var key in store) { result.push(store[key]); } return '[' + result.join(',') + ']'; }; /** *数组工具类 */ var Arrays = { /** *asList(elem0[, elem1[, elem2[,...]]]); *将指定一到多个元素转化成ArrayList */ asList: function() { return new ArrayList(Array.prototype.slice.call(arguments)); }, /** *binarySearch(ary, target, compareFn); *对有序数组进行二分查找 */ binarySearch: function(ary, target, compareFn) { Arrays.__aryCheck__(ary); if (target === undefined) throw Error('target must be specified'); return Arrays.binarySearchRange(ary, 0, ary.length, target, compareFn); }, /** *binarySearchRange(ary, fromIndex, toIndex, target, compareFn); *对有序数组指定范围进行二分查找 */ binarySearchRange: function(ary, fromIndex, toIndex, target, compareFn) { Arrays.__aryCheck__(ary); Arrays.__rangeCheck__(ary, fromIndex, toIndex); var low = fromIndex, high = toIndex - 1, mid, compareFnDefined = compareFn && typeof compareFn === 'function', compareResult; while (low <= high) { mid = Math.floor((low + high) >> 1); if (compareFnDefined) { compareResult = compareFn(ary[mid], target); } else { compareResult = ary[mid] - target; } if (compareResult < 0) { low = mid + 1; } else if (compareResult > 0) { high = mid - 1; } else { return mid; } } return -1; }, /** *复制指定数组内指定长度的元素 */ copyOf: function(ary, length) { Arrays.__aryCheck__(ary); if (length === undefined) { return ary.slice(0, ary.length); } if (typeof length !== 'number') { throw TypeError('length is not a number'); } return Arrays.copyOfRange(ary, 0, length); }, /** *复制指定数组内指定范围的元素 */ copyOfRange: function(ary, fromIndex, toIndex) { Arrays.__rangeCheck__(ary, fromIndex, toIndex); return ary.slice(fromIndex, toIndex); }, /** *两个指定数组是否相等 */ equals: function(ary0, ary1, equalsFn) { if (ary0 === ary1) return true; if (ary0.length !== ary1.length) return false; var equalsFnDefined = equalsFn && typeof equalsFn === 'function', isEquals; for (var i = 0, len = ary0.length; i < len; i++) { if (equalsFnDefined) { isEquals = equalsFn(ary0[i], ary1[i]); } else { isEquals = ary0[i] === ary1[i]; } if (isEquals) return true; } return false; }, /** *用指定元素填充指定数组 */ fill: function(ary, elem) { Arrays.fillRange(ary, 0, ary.length, elem); }, /** *用指定元素填充指定数组的指定范围 */ fillRange: function(ary, fromIndex, toIndex, elem) { Arrays.__rangeCheck__(ary, fromIndex, toIndex); for (var i = fromIndex; i < toIndex; i++) { ary[i] = elem; } }, /** *对指定数组排序 */ sort: function(ary, compareFn) { return Arrays.sortRange(ary, 0, ary.length, compareFn); }, /** *对指定数组指定范围排序 */ sortRange: function(ary, fromIndex, toIndex, compareFn) { Arrays.__rangeCheck__(ary, fromIndex, toIndex); var quickSort = function(ary) { if (ary.length <= 1) return ary; var pivotIndex = Math.floor(ary.length >> 1), pivot = ary.splice(pivotIndex, 1)[0], left = [], right = [], compareFnDefined = compareFn && typeof compareFn === 'function', compareResult; for (var i = 0, len = ary.length; i < len; i++) { if (compareFnDefined) { compareResult = compareFn(ary[i], pivot); } else { compareResult = ary[i] - pivot; } if (compareResult < 0) { left.push(ary[i]); } else { right.push(ary[i]); } } return quickSort(left).concat([pivot], quickSort(right)); }; return quickSort(fromIndex === 0 && toIndex === 0 ? ary : ary.slice(fromIndex, toIndex)); }, __aryCheck__: function(ary) { if (!(ary instanceof Array)) { throw TypeError('not an Array'); } }, __rangeCheck__: function(ary, fromIndex, toIndex) { if (typeof fromIndex !== 'number' || typeof toIndex !== 'number') { throw TypeError('fromIndex or toIndex must be a number'); } else if (fromIndex < 0 || fromIndex > ary.length) { throw Error('fromIndex out of bounds'); } else if (toIndex < 0 || toIndex > ary.length) { throw Error('toIndex out of bounds'); } else if (fromIndex > toIndex) { throw Error('fromIndex > toIndex'); } } }; /** *集合工具类 */ var Collections = { /** *取得集合中最大的元素 */ max: function(collection, compareFn) { Collections.__collectionCheck__(collection); if (collection.isEmpty()) throw Error('collection is empty'); var iter = collection.iterator(), result = iter.next(), current, compareFnDefined = compareFn && typeof compareFn === 'function', compareResult; while (iter.hasNext()) { current = iter.next(); if (compareFnDefined) { compareResult = compareFn(current, result); } else { compareResult = current - result; } if (compareResult > 0) { result = current; } } return result; }, /** *取得集合中最小的元素 */ min: function(collection, compareFn) { Collections.__collectionCheck__(collection); if (collection.isEmpty()) throw Error('collection is empty'); var iter = collection.iterator(), result = iter.next(), current, compareFnDefined = compareFn && typeof compareFn === 'function', compareResult; while (iter.hasNext()) { current = iter.next(); if (compareFnDefined) { compareResult = compareFn(current, result); } else { compareResult = current - result; } if (compareResult < 0) { result = current; } } return result; }, /** *对List进行排序 */ sort: function(list, compareFn) { Collections.__listCheck__(list); if (list.isEmpty()) return; var ary = Arrays.sort(list.toArray(), compareFn); for (var i = 0, len = ary.length; i < len; i++) { list.set(i, ary[i]); } }, /** *对有序List进行二分查找 返回索引值 */ binarySearch: function(list, target, compareFn) { Collections.__listCheck__(list); return Arrays.binarySearch(list.toArray(), target, compareFn); }, /** *将List中的指定元素全部替换为新元素 */ replaceAll: function(list, oldElem, newElem) { Collections.__listCheck__(list); var replaced = false, iter = list.iterator(); while (iter.hasNext()) { if (list.__equals__(oldElem, iter.next())) { iter.set(newElem); replaced = true; } } return replaced; }, /** *将List元素反转 */ reverse: function(list) { Collections.__listCheck__(list); var size = list.size(); if (list instanceof ArrayList) { for (var i = 0, mid = size >> 1, j = size - 1; i < mid; i++, j--) { list.set(i, list.set(j, list.get(i))); } } else if (list instanceof LinkedList) { var forward = list.iterator(), backward = list.iterator(list.size()), temp; for (var i = 0, mid = size >> 1; i < mid; i++) { temp = forward.next(); forward.set(backward.previous()); backward.set(temp); } } }, __listCheck__: function(list) { if (!(list instanceof List)) throw TypeError('not a List'); }, __collectionCheck__: function(collection) { if (!(collection instanceof Collection)) throw TypeError('not a Collection'); } }; //Object.keys是ECMAScript 5th Edition中新增函数 if (!Object.keys) {//如果不是现代浏览器则实现一个Object.keys函数 Object.keys = (function () { var hasOwnProperty = Object.prototype.hasOwnProperty, hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'), dontEnums = ['toString', 'toLocaleString', 'valueOf', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'constructor'], dontEnumsLength = dontEnums.length; return function (obj) { if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) { throw TypeError('Object.keys called on non-object'); } var result = [], prop, i; for (prop in obj) { if (hasOwnProperty.call(obj, prop)) { result.push(prop); } } if (hasDontEnumBug) { for (i = 0; i < dontEnumsLength; i++) { if (hasOwnProperty.call(obj, dontEnums[i])) { result.push(dontEnums[i]); } } } return result; }; }()); }; var collections = {};//collections包 collections.Collection = Collection;//Collection接口 collections.List = List;//List接口 collections.Set = Set;//Set接口 collections.Map = Map;//Map接口 collections.ArrayList = ArrayList; collections.LinkedList = LinkedList; collections.HashSet = HashSet; collections.HashMap = HashMap; collections.Arrays = Arrays; collections.Collections = Collections; collections.__hash__ = 1024;//用于标识对象 global.collections = collections;//将collections包放置在全局区 //将某个模块导入到全局区 例如imports('collections.*'); var globalImports = function(module) { if (!/^collections\.(\*|[a-zA-Z]+)$/g.test(module)) { throw Error('imports function arguments error'); } module = module.replace('collections.', ''); if (module === '*') { for (var elem in collections) { global[elem] = collections[elem]; } } else { collections[module] && (global[module] = collections[module]); } }, isModule = false; if (typeof define === 'function') {// RequireJS || SeaJS define(function(require, exports, module) { module.exports = collections; isModule = true; }); } else if (typeof exports !== 'undefined') {// NodeJS module.exports = collections; isModule = true; } else { global.imports = globalImports; } if (isModule) { //for RequireJS || SeaJS || NodeJS //var collections = require('./collections'); //collections.imports('*'); collections.imports = function(module) { globalImports('collections.' + module); }; } })(this);