Skip to content

Instantly share code, notes, and snippets.

@synther
Created November 23, 2011 17:38
Show Gist options
  • Save synther/1389324 to your computer and use it in GitHub Desktop.
Save synther/1389324 to your computer and use it in GitHub Desktop.
Attempt to make a lambda-like construction in Java
package lambdatest;
import java.lang.reflect.InvocationTargetException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Попытка сделать что-то похожее на лямбды не используя паттерн Command.
* Треш, кишки и расчлененка.
*
* Выполнение примера:
* run:
* foreach:
* = 1
* = 2
* = 3
* = 4
* = 5
*
* sum:
* 15
* BUILD SUCCESSFUL (total time: 0 seconds)
*
* Проблемы, которые пока не решены:
* - дурацкий if (!init) {
* - ни разу не thread-safe
* - при перемещении lambda-классов в другой пакет все ломается
*
* @author synther
*/
public class LambdaTest {
public static void main(String[] args) throws Exception {
final Integer[] nums = new Integer[]{1, 2, 3, 4, 5};
System.out.println("foreach:");
forEach(nums, new A1<Object, Object>() {{if (!init) {
System.out.println("= " + x1);
}}});
System.out.println("");
System.out.println("sum:");
int sum = fold(nums, new A2<Integer, Integer, Integer>(){{if (!init) {
result(x1 + x2);
}}});
System.out.println(sum);
}
static void forEach(Object[] objects, A1<Object, Object> action) {
for (Object object : objects) {
action.apply(object);
}
}
static int fold(Integer[] integers, A2<Integer, Integer, Integer> action) {
if (integers.length == 0) {
return 0;
}
int result = integers[0];
for (int i = 1; i < integers.length; i++) {
result = action.apply(result, integers[i]);
}
return result;
}
}
class A<R> extends LambdaCore<R, Object, Object, Object> {
public R apply() {
return apply(new Object[]{});
}
}
class A1<R, T1> extends LambdaCore<R, T1, Object, Object> {
protected T1 x1;
public R apply(T1 arg1) {
return apply(new Object[]{arg1});
}
}
class A2<R, T1, T2> extends LambdaCore<R, T1, T2, Object> {
protected T1 x1;
protected T2 x2;
public R apply(T1 arg1, T2 arg2) {
return apply(new Object[]{arg1, arg2});
}
}
class A3<R, T1, T2, T3> extends LambdaCore<R, T1, T2, T3> {
protected T1 x1;
protected T2 x2;
protected T2 x3;
public R apply(T1 arg1, T2 arg2) {
return apply(new Object[]{arg1, arg2});
}
}
abstract class LambdaCore<R, T1, T2, T3> {
final protected boolean init;
private R resultValue;
private static Object params = null;
public LambdaCore() {
if ("newInstance0".equals(Thread.currentThread().getStackTrace()[4].getMethodName())) {
// Предполагаем что вызвано из apply()
try {
Object[] paramsArray = (Object[]) params;
if (paramsArray != null) {
if (paramsArray.length >= 1) {
this.getClass().getSuperclass().getDeclaredField("x1").set(this, (T1) (paramsArray[0]));
}
if (paramsArray.length >= 2) {
this.getClass().getSuperclass().getDeclaredField("x2").set(this, (T2) (paramsArray[1]));
}
if (paramsArray.length >= 3) {
this.getClass().getSuperclass().getDeclaredField("x3").set(this, (T3) (paramsArray[2]));
}
}
} catch (IllegalArgumentException ex) {
Logger.getLogger(LambdaCore.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(LambdaCore.class.getName()).log(Level.SEVERE, null, ex);
} catch (NoSuchFieldException ex) {
Logger.getLogger(LambdaCore.class.getName()).log(Level.SEVERE, null, ex);
} catch (SecurityException ex) {
Logger.getLogger(LambdaCore.class.getName()).log(Level.SEVERE, null, ex);
}
init = false;
} else {
// Предполагаем что вызвано при создании лямбды. Нужно предвратить выполнение
// конструктора анонимного класса
init = true;
}
}
protected R apply(Object... args) {
try {
params = args;
LambdaCore newInstance = this.getClass().getDeclaredConstructor().newInstance();
return (R) newInstance.resultValue;
} catch (InstantiationException ex) {
Logger.getLogger(LambdaCore.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(LambdaCore.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalArgumentException ex) {
Logger.getLogger(LambdaCore.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvocationTargetException ex) {
Logger.getLogger(LambdaCore.class.getName()).log(Level.SEVERE, null, ex);
} catch (NoSuchMethodException ex) {
Logger.getLogger(LambdaCore.class.getName()).log(Level.SEVERE, null, ex);
} catch (SecurityException ex) {
Logger.getLogger(LambdaCore.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
protected void result(R r) {
this.resultValue = r;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment