javascript函数库-集合框架

 更新时间:2007年04月27日 00:00:00   作者:  
Classes:
Collections
Arrays
ArrayList
SortedList extends ArrayList
HashMap
HashSet
*/

/****************
Collections
NOTE:sort() return a new List
****************/
function Collections(){}
Collections.sort=function(){
if(arguments.length==1){
 var s=new SortedList();
 s.addAll(arguments[0]);
 return s;
}
else if(arguments.length==2){
 var s=new SortedList();
 s.setComparator(arguments[1]);
 s.addAll(arguments[0]);
 return s;
}
else 
 throw "IllegalArgument";
}
/***************
Arrays
****************/
function Arrays(){}
Arrays.asList=function(arr){
return new ArrayList(arr);
}


//ListIterator
function ListIterator(table,len){
   this.table=table;
this.len=len;                          
   this.index=0;
 
this.hasNext=function() {
&nbsp;return this.index< this.len;
&nbsp; &nbsp;}

&nbsp; &nbsp;this.next=function() { 
&nbsp;if(!this.hasNext())
&nbsp; throw "No such Element!";
&nbsp;return this.table[this.index++];
&nbsp; &nbsp;}
}

/********************
ArrayList
********************/
function ArrayList(){
this.buffer=new Array();
if(arguments.length>0) this.buffer=arguments[0];
this.length=this.buffer.length;
}
ArrayList.prototype.hashCode=function(){
var h=0;
for(var i=0;i<this.lengh;i++)
&nbsp;h+=this.buffer[i].hashCode();
return h;
}

ArrayList.prototype.size=function(){
return this.length;
}

ArrayList.prototype.clear=function(){
for(var i=0;i<this.length;i++) this.buffer[i]=null;
this.buffer.length=0;
this.length=0;
}

ArrayList.prototype.isEmpty=function(){
return this.length==0;
}

ArrayList.prototype.toArray=function(){
var copy=new Array();
for(var i=0;i<this.length;i++){
&nbsp;copy[i]=this.buffer[i];
}
return copy;
}
ArrayList.prototype.get=function(index){
if(index>=0 && index<this.length)
&nbsp;return this.buffer[index];
return null;
}

ArrayList.prototype.remove=function(param){
var index=0;
&nbsp;
if(isNaN(param)){
&nbsp;index=this.indexOf(param);
}
else index=param;
&nbsp; 
if(index>=0 && index<this.length){
&nbsp;for(var i=index;i<this.length-1;i++)
&nbsp; this.buffer[i]=this.buffer[i+1];
&nbsp; this.length-=1;
&nbsp; return true;
}
else return false;
}
&nbsp;
ArrayList.prototype.add=function(){
var args=arguments;
if(args.length==1){
&nbsp;this.buffer[this.length++]=args[0];
&nbsp;return true;
}
else if(args.length==2){
&nbsp;var index=args[0];
&nbsp;var obj=args[1];
&nbsp;if(index>=0 && index<=this.length){
&nbsp; for(var i=this.length;i>index;i--)
&nbsp; &nbsp;this.buffer[i]=this.buffer[i-1];
&nbsp; this.buffer[i]=obj;
&nbsp; this.length+=1;
&nbsp; return true;
&nbsp;}
}
return false;
}

ArrayList.prototype.indexOf=function(obj){
for(var i=0;i<this.length;i++){
&nbsp;if(this.buffer[i].equals(obj)) return i;
}
return -1;
}

ArrayList.prototype.lastIndexOf=function(obj){
for(var i=this.length-1;i>=0;i--){
&nbsp;if(this.buffer[i].equals(obj)) return i;
}
return -1;
}

ArrayList.prototype.contains=function(obj){
return this.indexOf(obj)!=-1;
}

ArrayList.prototype.equals=function(obj){
if(this.size()!=obj.size()) return false;
for(var i=0;i<this.length;i++){
&nbsp;if(!obj.get(i).equals(this.buffer[i])) return false;
}
return true;
}

ArrayList.prototype.addAll=function(list){
var mod=false;
for(var it=list.iterator();it.hasNext();){
&nbsp;var v=it.next();
&nbsp;if(this.add(v)) mod=true;
}
return mod; &nbsp;
}

ArrayList.prototype.containsAll=function(list){
for(var i=0;i<list.size();i++){
&nbsp;if(!this.contains(list.get(i))) return false;
}
return true;
}

ArrayList.prototype.removeAll=function(list){
for(var i=0;i<list.size();i++){
&nbsp;this.remove(this.indexOf(list.get(i)));
}
}

ArrayList.prototype.retainAll=function(list){
for(var i=this.length-1;i>=0;i--){
&nbsp;if(!list.contains(this.buffer[i])){
&nbsp; this.remove(i);
&nbsp;}
}
}

ArrayList.prototype.subList=function(begin,end){
if(begin<0) begin=0;
if(end>this.length) end=this.length;
var newsize=end-begin;
var newbuffer=new Array();
for(var i=0;i<newsize;i++){
&nbsp;newbuffer[i]=this.buffer[begin+i];
}
return new ArrayList(newbuffer);
}
ArrayList.prototype.set=function(index,obj){
if(index>=0 && index<this.length){
&nbsp;temp=this.buffer[index];
&nbsp;this.buffer[index]=obj;
&nbsp;return temp;
}
}

ArrayList.prototype.iterator=function iterator(){
return new ListIterator(this.buffer,this.length);
}

/*****************************
SortedList extends ArrayList
*****************************/
function SortedList(){
&nbsp; this.com=null;
}
SortedList.prototype=new ArrayList();
SortedList.prototype.setComparator=function(comp){
if(this.length!=0) throw "Only can be set when list is empty";
this.com=comp;
}

SortedList.prototype.getComparator=function(){
return this.com;
}

//override
SortedList.prototype.add=function(obj){
var index = this.indexOf(obj);
for(var i=this.length;i>index;){
&nbsp;this.buffer[i]=this.buffer[--i];
}

this.buffer[index]=obj;
this.length++; 
}
//override
SortedList.prototype.indexOf=function(obj){
if(this.length==0) return 0;
&nbsp;
var min=0,max=this.length-1;
var mid=0;
while(min<=max){
&nbsp; 
&nbsp;mid = (min+max) >> 1;
&nbsp;var c=0;
&nbsp;if(this.com==null) c=obj.compareTo(this.buffer[mid]);
&nbsp;else c=this.com.compare(obj,this.buffer[mid]);
&nbsp; 
&nbsp;if(c==0){
&nbsp; return mid;
&nbsp;}
&nbsp;else if(c<0){
&nbsp; max=mid-1;
&nbsp;}
&nbsp;else{
&nbsp; min=mid+1;
&nbsp;}
}
mid =(min+max) >>1;
return mid+1;
}
//override
SortedList.prototype.contains=function(obj){
if(this.length==0) return false;
var min=0,max=this.length-1;
var mid=0;
while(min<=max){
&nbsp;mid = (min+max) >> 1;
&nbsp;var c=0;
&nbsp;if(this.com==null) c=obj.compareTo(this.buffer[mid]);
&nbsp;else &nbsp;c=this.com.compare(obj,this.buffer[mid]);
&nbsp;if(c==0){
&nbsp; return true;
&nbsp;}
&nbsp;else if(c<0){
&nbsp; max=mid-1;
&nbsp;}
&nbsp;else{
&nbsp; min=mid+1;
&nbsp;}
}
return false;
}
//override
SortedList.prototype.subList=function(begin,end){
var sl=new SortedList();
s1.setComparator(this.com);
var sub=ArrayList.prototype.subList(begin.end);
sl.addAll(sub);
return sl;
}


/****************************
HashMap
****************************/

function Entry(h,k,v,n){
&nbsp; this.value = v; 
&nbsp; this.next = n;
&nbsp; this.key = k;
&nbsp; this.hash = h;

&nbsp; this.getKey=function(){
&nbsp;return this.key;
&nbsp; }

&nbsp; this.getValue=function() {
&nbsp;return this.value;
&nbsp; }
&nbsp; this.setValue=function(newValue) {
&nbsp;var oldValue = this.value;
&nbsp;this.value = newValue;
&nbsp;return oldValue;
&nbsp; }

&nbsp; this.equals=function(o){
&nbsp; var e = o;
&nbsp; var k1 = this.getKey();
&nbsp; var k2 = e.getKey();
&nbsp; var v1 = this.getValue();
&nbsp; var v2 = e.getValue();
&nbsp; return (k1.equals(k2) && v1.equals(v2));
&nbsp; }

&nbsp; this.hashCode=function() {
&nbsp; &nbsp;return this.key.hashCode() ^ this.value.hashCode();
&nbsp; }

&nbsp; this.toString=function() {
&nbsp;return this.getKey() + "=" + this.getValue();
&nbsp; }
}

function HashIterator(table,index,ne){

this.table=table;
this.ne=ne; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
this.index=index; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
this.current=null;

this.hasNext=function() {
&nbsp;return this.ne != null;
}

this.next=function() { 
&nbsp;
&nbsp;var e = this.ne;
&nbsp;if (e == null) 
&nbsp; throw "No such Element";
&nbsp; &nbsp;
&nbsp;var n = e.next;
&nbsp;var t = this.table;
&nbsp;var i = this.index;
&nbsp;while (n == null && i > 0)
&nbsp; n = t[--i];
&nbsp;this.index = i;
&nbsp;this.ne = n;
&nbsp;this.current=e;

&nbsp;return this.current;
}
}


function HashMap()
{
this.len=8;
this.table=new Array();
this.length=0;
}
// refer to java.util.HashMap
HashMap.hash=function(x){
&nbsp; &nbsp;var h = x.hashCode();
&nbsp; &nbsp;h += ~(h << 9);
&nbsp; &nbsp;h ^= &nbsp;(h >>> 14);
&nbsp; &nbsp;h += &nbsp;(h << 4);
&nbsp; &nbsp;h ^= &nbsp;(h >>> 10);
&nbsp; &nbsp;return h;
}

HashMap.prototype.rehash=function(){ &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp;var oldTable = this.table; &nbsp; 
&nbsp; &nbsp;this.table=new Array();
&nbsp; &nbsp; &nbsp; &nbsp;
//transfer &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp;for (var i = 0; i< oldTable.length; i++) {
&nbsp; &nbsp; &nbsp; &nbsp;var e = oldTable[i];
&nbsp; &nbsp; &nbsp; &nbsp;if (e != null) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; oldTable[i] = null;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; do {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var next = e.next;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var j = this.indexFor(e.hash); &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.next = this.table[j];
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.table[j] = e;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e = next;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} while (e != null);
&nbsp; &nbsp; &nbsp; &nbsp;}
&nbsp; &nbsp;}
}

HashMap.prototype.indexFor=function(h) {
var index= h & (this.len-1);
return index;
}

HashMap.prototype.size=function() {
return this.length;
}

HashMap.prototype.isEmpty=function() {
return this.length == 0;
}

HashMap.prototype.get=function(key) {
var hash =HashMap.hash(key);
var i = this.indexFor(hash);

var e = this.table[i]; 

while (true) {
&nbsp;if (e ==null)
&nbsp; return null;
&nbsp;if (e.hash == hash && key.equals(e.key)) 
&nbsp; return e.value;
&nbsp;e = e.next;
}
}

HashMap.prototype.containsKey=function(key) {
var hash =HashMap.hash(key);
var i = this.indexFor(hash);
var e = this.table[i]; 

while (e != null) {
&nbsp;if (e.hash == hash && key.equals(e.key)) 
&nbsp; return true;
&nbsp;e = e.next;
}
return false;
}

HashMap.prototype.put=function(key,value) {
var hash = HashMap.hash(key);
var i = this.indexFor(hash);


for (var e = this.table[i]; e != null; e = e.next) {
&nbsp;if (e.hash == hash && key.equals(e.key)) {
&nbsp; var oldValue = e.value;
&nbsp; e.value = value;
&nbsp; return oldValue;
&nbsp;}
}

this.addEntry(hash, key, value, i);

var r=Math.ceil(this.length * 1.5);

if(r > this.len){
&nbsp;this.len= this.len << 1;
&nbsp;this.rehash();
}
return null;
}


HashMap.prototype.putAll=function (map){
var mod=false;
for(var it=map.iterator();it.hasNext();){
&nbsp;var e=it.next();
&nbsp;if(this.put(e.getKey(),e.getValue())) mod=true;
}
}

HashMap.prototype.remove=function(key) {
&nbsp; &nbsp;var e = this.removeEntryForKey(key); 
&nbsp; &nbsp;return (e ==null ? null : e.value);
}

HashMap.prototype.removeEntryForKey=function(key) {
var hash = HashMap.hash(key);
var i = this.indexFor(hash);

var prev = this.table[i];
var e = prev;

while (e != null) {
&nbsp;var next = e.next;
&nbsp;if (e.hash == hash && key.equals(e.key)) {
&nbsp; this.length--;
&nbsp; if (prev.equals(e)) 
&nbsp; &nbsp;this.table[i] = next;
&nbsp; else
&nbsp; &nbsp;prev.next = next;
&nbsp; return e;
&nbsp;}
&nbsp;prev = e;
&nbsp;e = next;
}
return e;
}

HashMap.prototype.clear=function() {
&nbsp; &nbsp;for (var i = 0; i < this.table.length; i++) 
&nbsp; &nbsp; &nbsp; &nbsp;this.table[i] = null;
&nbsp; &nbsp;this.length = 0;
}

HashMap.prototype.containsValue=function(value) {
if (value == null) return false;

var tab = this.table;
for (var i = 0; i < tab.length ; i++)
&nbsp;for (var e = tab[i] ; e != null ; e = e.next)
&nbsp; if (value.equals(e.value))
&nbsp; &nbsp;return true;
return false;
}

HashMap.prototype.addEntry=function(hash, key, value, bucketIndex) {
this.table[bucketIndex] = new Entry(hash, key, value, this.table[bucketIndex]);
this.length++;
}

HashMap.prototype.iterator=function(){
var i=this.table.length;

var next=null;
while(i>0 && next==null){
&nbsp;next=this.table[--i];
}

return new HashIterator(this.table,i,next);
}


HashMap.prototype.hashCode=function(){
var h=0;
for(var it=this.iterator();it.hasNext();){
&nbsp;h+=it.next().hashCode();
}
return h;
}

HashMap.prototype.equals=function(map){
if(!this.typeMatches(map)) return false;
if(map.size()!=this.size()) return false;

for(var it=this.iterator();it.hasNext();){ 
&nbsp;var e=it.next();
&nbsp;var key=e.getKey();
&nbsp;var value=e.getValue();

&nbsp;if(!value.equals(map.get(key))) return false

}
return true;
}


/*************************
HashSet
**************************/

function HashSetIterator(ite){
&nbsp; &nbsp;this.it=ite;
&nbsp;
this.hasNext=function() {
&nbsp;return this.it.hasNext();
&nbsp; &nbsp;}

&nbsp; &nbsp;this.next=function() { 
&nbsp;return this.it.next().getKey();
&nbsp; &nbsp;}
}

function HashSet(){ &nbsp;
this.map=new HashMap();
}
HashSet.NULL=new Number("!THIS IS NULL!");


HashSet.prototype.size=function(){
return this.map.size();
}

HashSet.prototype.isEmpty=function() {
return this.map.isEmpty();
}

HashSet.prototype.contains=function(o) {
return this.map.containsKey(o);
}

HashSet.prototype.add=function(o){
return this.map.put(o,HashSet.NULL)==null;
}

HashSet.prototype.addAll=function(set){
var mod=false;
for(var it=set.iterator();it.hasNext();){
&nbsp;if(this.add(it.next())) mod=true;
}
return mod;
}

HashSet.prototype.remove=function(o) {
return this.map.remove(o).equals(HashSet.NULL);
}

HashSet.prototype.clear=function() {
this.map.clear();
}

HashSet.prototype.iterator=function(){
return new HashSetIterator(this.map.iterator());
}

HashSet.prototype.equals=function(o) {
if(!this.typeMatches(o)) return false;
if (o.size() != this.size()) return false;
for(var it=this.iterator();it.hasNext();){
&nbsp;if(!o.contains(it.next())) return false;
}
return true;
}

HashSet.prototype.hashCode=function() {
var h=0;
for(var it=this.iterator();it.hasNext();){
&nbsp;h+=it.next().hashCode();
}
return h;
}

HashSet.prototype.toArray=function(){
var arr=new Array();
var i=0;
for(var it=this.iterator();it.hasNext();){
&nbsp;arr[i++]=it.next();
}
return arr;
}

相关文章

最新评论