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() {
return this.index }
this.next=function() {
if(!this.hasnext())
throw no such element!;
return this.table[this.index++];
}
}
/********************
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 h+=this.buffer[i].hashcode();
return h;
}
arraylist.prototype.size=function(){
return this.length;
}
arraylist.prototype.clear=function(){
for(var i=0;ithis.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 copy[i]=this.buffer[i];
}
return copy;
}
arraylist.prototype.get=function(index){
if(index>=0 && index return this.buffer[index];
return null;
}
arraylist.prototype.remove=function(param){
var index=0;
if(isnan(param)){
index=this.indexof(param);
}
else index=param;
if(index>=0 && index for(var i=index;i this.buffer[i]=this.buffer[i+1];
this.length-=1;
return true;
}
else return false;
}
arraylist.prototype.add=function(){
var args=arguments;
if(args.length==1){
this.buffer[this.length++]=args[0];
return true;
}
else if(args.length==2){
var index=args[0];
var obj=args[1];
if(index>=0 && index for(var i=this.length;i>index;i--)
this.buffer[i]=this.buffer[i-1];
this.buffer[i]=obj;
this.length+=1;
return true;
}
}
return false;
}
arraylist.prototype.indexof=function(obj){
for(var i=0;i if(this.buffer[i].equals(obj)) return i;
}
return -1;
}
arraylist.prototype.lastindexof=function(obj){
for(var i=this.length-1;i>=0;i--){
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 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();){
var v=it.next();
if(this.add(v)) mod=true;
}
return mod;
}
arraylist.prototype.containsall=function(list){
for(var i=0;i if(!this.contains(list.get(i))) return false;
}
return true;
}
arraylist.prototype.removeall=function(list){
for(var i=0;i this.remove(this.indexof(list.get(i)));
}
}
arraylist.prototype.retainall=function(list){
for(var i=this.length-1;i>=0;i--){
if(!list.contains(this.buffer[i])){
this.remove(i);
}
}
}
arraylist.prototype.sublist=function(begin,end){
if(beginif(end>this.length) end=this.length;
var newsize=end-begin;
var newbuffer=new array();
for(var i=0;i newbuffer[i]=this.buffer[begin+i];
}
return new arraylist(newbuffer);
}
arraylist.prototype.set=function(index,obj){
if(index>=0 && index temp=this.buffer[index];
this.buffer[index]=obj;
return temp;
}
}
arraylist.prototype.iterator=function iterator(){
return new listiterator(this.buffer,this.length);
}
/*****************************
sortedlist extends arraylist
*****************************/
function sortedlist(){
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;){
this.buffer[i]=this.buffer[--i];
}
this.buffer[index]=obj;
this.length++;
}
//override
sortedlist.prototype.indexof=function(obj){
if(this.length==0) return 0;
var min=0,max=this.length-1;
var mid=0;
while(min
mid = (min+max) >> 1;
var c=0;
if(this.com==null) c=obj.compareto(this.buffer[mid]);
else c=this.com.compare(obj,this.buffer[mid]);
if(c==0){
return mid;
}
else if(c max=mid-1;
}
else{
min=mid+1;
}
}
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 mid = (min+max) >> 1;
var c=0;
if(this.com==null) c=obj.compareto(this.buffer[mid]);
else c=this.com.compare(obj,this.buffer[mid]);
if(c==0){
return true;
}
else if(c max=mid-1;
}
else{
min=mid+1;
}
}
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){
this.value = v;
this.next = n;
this.key = k;
this.hash = h;
this.getkey=function(){
return this.key;
}
this.getvalue=function() {
return this.value;
}
this.setvalue=function(newvalue) {
var oldvalue = this.value;
this.value = newvalue;
return oldvalue;
}
this.equals=function(o){
var e = o;
var k1 = this.getkey();
var k2 = e.getkey();
var v1 = this.getvalue();
var v2 = e.getvalue();
return (k1.equals(k2) && v1.equals(v2));
}
this.hashcode=function() {
return this.key.hashcode() ^ this.value.hashcode();
}
this.tostring=function() {
return this.getkey() + = + this.getvalue();
}
}
function hashiterator(table,index,ne){
this.table=table;
this.ne=ne;
this.index=index;
this.current=null;
this.hasnext=function() {
return this.ne != null;
}
this.next=function() {
var e = this.ne;
if (e == null)
throw no such element;
var n = e.next;
var t = this.table;
var i = this.index;
while (n == null && i > 0)
n = t[--i];
this.index = i;
this.ne = n;
this.current=e;
return this.current;
}
}
function hashmap()
{
this.len=8;
this.table=new array();
this.length=0;
}
// refer to java.util.hashmap
hashmap.hash=function(x){
var h = x.hashcode();
h += ~(h h ^= (h >>> 14);
h += (h h ^= (h >>> 10);
return h;
}
hashmap.prototype.rehash=function(){
var oldtable = this.table;
this.table=new array();
//transfer
for (var i = 0; i var e = oldtable[i];
if (e != null) {
oldtable[i] = null;
do {
var next = e.next;
var j = this.indexfor(e.hash);
e.next = this.table[j];
this.table[j] = e;
e = next;
} while (e != null);
}
}
}
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) {
if (e ==null)
return null;
if (e.hash == hash && key.equals(e.key))
return e.value;
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) {
if (e.hash == hash && key.equals(e.key))
return true;
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) {
if (e.hash == hash && key.equals(e.key)) {
var oldvalue = e.value;
e.value = value;
return oldvalue;
}
}
this.addentry(hash, key, value, i);
var r=math.ceil(this.length * 1.5);
if(r > this.len){
this.len= this.len this.rehash();
}
return null;
}
hashmap.prototype.putall=function (map){
var mod=false;
for(var it=map.iterator();it.hasnext();){
var e=it.next();
if(this.put(e.getkey(),e.getvalue())) mod=true;
}
}
hashmap.prototype.remove=function(key) {
var e = this.removeentryforkey(key);
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) {
var next = e.next;
if (e.hash == hash && key.equals(e.key)) {
this.length--;
if (prev.equals(e))
this.table[i] = next;
else
prev.next = next;
return e;
}
prev = e;
e = next;
}
return e;
}
hashmap.prototype.clear=function() {
for (var i = 0; i this.table[i] = null;
this.length = 0;
}
hashmap.prototype.containsvalue=function(value) {
if (value == null) return false;
var tab = this.table;
for (var i = 0; i for (var e = tab[i] ; e != null ; e = e.next)
if (value.equals(e.value))
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){
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();){
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();){
var e=it.next();
var key=e.getkey();
var value=e.getvalue();
if(!value.equals(map.get(key))) return false
}
return true;
}
/*************************
hashset
**************************/
function hashsetiterator(ite){
this.it=ite;
this.hasnext=function() {
return this.it.hasnext();
}
this.next=function() {
return this.it.next().getkey();
}
}
function hashset(){
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();){
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();){
if(!o.contains(it.next())) return false;
}
return true;
}
hashset.prototype.hashcode=function() {
var h=0;
for(var it=this.iterator();it.hasnext();){
h+=it.next().hashcode();
}
return h;
}
hashset.prototype.toarray=function(){
var arr=new array();
var i=0;
for(var it=this.iterator();it.hasnext();){
arr[i++]=it.next();
}
return arr;
}