2007/11/14

Original Code: CQL - Smalltalk/Ruby/SQL liked collection query and operation library

Do class can perform smalltalk/ruby liked collection based foreach operation. It's especially useful on complicated collection sql liked select operation.

* note the operation is not well tuned. you should implement with java native methods when performance is important for your application.

Example
The following code demostrate how to select elements in SQL-like style.
The code is pretty long than Small/Ruby/SQL, most of the are type defination and can be auto-generated by moden programming tools like Eclipse, Idea and NetBeans.

/** self test main function, usage demo */
public static void main (String[] argv) {
try {
// declare a array
Integer[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

new Do<Integer>(arr)
// select * from arr where arr.value > 3
.select(new Do.BoolFunc<Integer>() {
public boolean exec(int index, Object key, Integer value) {
return value >= 2;
}
})
// and arr.value < 3
.select(new Do.BoolFunc<Integer>() {
public boolean exec(int index, Object key, Integer value) {
return value <= 8;
}
})
// dump the result
.exec(new Do.VoidFunc<Integer>() {
public void exec(int index, Object key, Integer value) {
System.out.println("[" + index + "]=" + value + ", key ['" + key + "']=" + value);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}

The result is shown as following.

[0]=2, key ['1']=2
[1]=3, key ['2']=3
[2]=4, key ['3']=4
[3]=5, key ['4']=5
[4]=6, key ['5']=6
[5]=7, key ['6']=7
[6]=8, key ['7']=8


package my.lang;

import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.HashMap;
import java.util.Map;

/**
* Do class can perform smalltalk/ruby liked collection based foreach operation.
* It's especially useful on complicated collection sql liked select operation.
* * note the operation is not well tuned.
* you should implement with java native methods
* when performance is important for your application.
* @author fantastechnol
* @param <T> the datatype of the content of your collection
*/
public class Do<T> {
// private data type constants
private final char NONE = 'N';
private final char ARRAY = 'A';
private final char COLLECTION = 'C';
private final char MAP = 'M';

// private constant
private T[] arr;
private Collection<T> coll;
private Map<Object, T> map;
private char type = NONE;

public interface BoolFunc<V> {
boolean exec (int index, Object key, V value);
}

public interface VoidFunc<V> {
void exec (int index, Object key, V value);
}

/** foreach array constructor */
public Do(T[] arr) {
this.arr = arr;
type = ARRAY;
}

/** foreach Collection constructor */
public Do(Collection<T> coll) {
this.coll = coll;
type = COLLECTION;
}

/** foreach Map constructor */
public Do(Map<Object, T> map) {
this.map = map;
type = MAP;
}

/** each */
public void exec (final VoidFunc<T> f) {
select(new BoolFunc<T>() {
public boolean exec(int index, Object key, T value) {
f.exec(index, key, value);
return false;
}
});
}

/**
* select all the BoolFunc returns true
* @param f BoolFunc
* @return ForEach object
*/
public Do<T> select (final BoolFunc<T> f) {
int i = 0;
Object key = null;
T value = null;
Map<Object, T> ret = new HashMap<Object, T>();

switch (type) {
case ARRAY:
for (; i < arr.length; i ++) {
key = Integer.valueOf(i);
value = arr[i];
if (f.exec(i, key, value)) {
ret.put(key, value);
}
}
break;
case COLLECTION:
for (Iterator<T> it = coll.iterator(); it.hasNext(); i ++) {
key = Integer.valueOf(i);
value = it.next();
if (f.exec(i, key, value)) {
ret.put(key, value);
}
}
break;
case MAP:
for (Iterator<Object> it = map.keySet().iterator(); it.hasNext(); i ++) {
key = it.next();
value = map.get(key);
if (f.exec(i, key, value)) {
ret.put(key, value);
}
}
break;
default:
new RuntimeException ("Invalid type: " + type
+ " arr: " + arr
+ " coll: " + coll
+ " map: " + map);
}
return new Do<T>(ret);
}


public Collection<T> getCollection() {
// TODO internal data structure maybe be modified by outside program

Collection<T> ret = null;

switch (type) {
case ARRAY:
ret = Arrays.asList(arr);
break;
case COLLECTION:
ret = coll;
break;
case MAP:
ret = map.values();
break;
default:
new RuntimeException ("Invalid type: " + type
+ " arr: " + arr
+ " coll: " + coll
+ " map: " + map);
}
return ret;
}

public Object[] getArray() {
// TODO internal data structure maybe be modified by outside program
// TODO cannot convert Collect<T>.toArray() type from object to <T>, or new T[]
Object[] ret = null;

switch (type) {
case ARRAY:
ret = arr;
break;
case COLLECTION:
ret = coll.toArray();
break;
case MAP:
ret = map.values().toArray();
break;
default:
new RuntimeException ("Invalid type: " + type
+ " arr: " + arr
+ " coll: " + coll
+ " map: " + map);
}
return ret;
}

public Map<Object, T> getMap() {
// TODO internal data structure maybe be modified by outside program
Map<Object, T> ret = null;

switch (type) {
case ARRAY:
ret = new Do<T>(arr).select(new BoolFunc<T> () {
public boolean exec (int index, Object key, T value) {
return true;
}
}).getMap();
break;
case COLLECTION:
ret = new Do<T>(coll).select(new BoolFunc<T> () {
public boolean exec (int index, Object key, T value) {
return true;
}
}).getMap();
break;
case MAP:
ret = map;
break;
default:
new RuntimeException ("Invalid type: " + type
+ " arr: " + arr
+ " coll: " + coll
+ " map: " + map);
}
return ret;
}
}

No comments: