我正在创建某种过滤系统,它基于不同的元素接受/产生相同类型的“上下文”。
例如,如下所示,可以对流程建模:
{generate_numbers(1..100)} --> {is_prime} --> {output}
上下文可以是一个简单的'HashMap'。 generate_numbers
创建上下文,其中'x'设置为某个数字is_prime
使用此上下文,查找'x'并相应地放置'prime'= true / false。
专业人士:
缺点:
这也是一种可行的方法,可以将所有内容声明为“上下文”中的字段,但这样可以牺牲容易扩展性(我可以忍受)
但是......情况有点复杂,因为这些transformator元素遍布整个应用程序的包:
{generate_numbers(1..100)} --> {is_prime} --> {calc(f_1)} --> {output}
{--------------- pkg_A ------------------} | {--------- pkg_B -------}
所以有些部分pkg_A可以工作,然后有些地方pkg_B部分处理上下文 - >这就是为什么我想混合两种方法
我想出了以下想法:
亲:
CON:
亲:
CON:
我完全错了,我应该以不同的方式解决问题
更新:
有“如何推广上下文类?”我的意思是如何创建一个相对方便的上下文,它将承载应用程序正在处理的所有混乱的东西,因为在当前的工作流程中,这些信息被控制逻辑模糊了
答案 0 :(得分:1)
我相信你会转到Scala:D。
Scala是一种具有OOP设计的函数式语言,它在Java虚拟机上运行,支持您刚刚提到的内容并具有强大的模式匹配引擎。
另一种方式可能涉及在Java中模拟功能范例,这几天前实际上已经超出了我的想法,但我做了太多工作而忘了它:D。
基本上,我在想的是你应该有一个界面
public interface Functionalizable {
public void map(Function f);
}
其中Function
也是一个可以扩展以编写自己的函数的接口。然后,一个这样的例子(可能不好,但那些是我在火车上旅行时的想法)可能是这样的:
public class FunctionList extends ArrayList implements Functionalizable {
public void map(Function f) {
// iterate over the elements of a list
// applying the function f on each of them
}
}
你可以这样称呼它:
List l = new FunctionList();
// add some data
l.map(
new Function() {
// some function
}
)
当然,这些代码实际上都不是可编译的,而只是我所思考的内容。是的,在Java中引入功能范例是一种痛苦,所以再一次,我最好的建议是坚持使用真正的函数式语言,比如Scala。 :d
答案 1 :(得分:0)
尝试传递元数据会让维护成为头痛的问题。相反,您需要functional programming解决方案,但特别是您希望处理list comprehensions - 在您的示例中为generate_numbers
函数。虽然你可以通过自己滚动来实现这一点 - 正如@Lopina建议的那样 - 通过创建一组function objects我认为更好的路径是使用现有的Java库。
特别是Google Guava有许多以这种方式对付Java集合的工具 - functional idioms就是你想要的。你必须编写自己的函数 - 在这种情况下是Guava Predicates - 在Guava的框架内使用,但我认为它为你描述的问题提供了正确的工具和抽象层次。 I found this question's answer particularly helpful understanding predicates。
import java.util.Arrays;
import com.google.common.base.Predicate;
import com.google.common.collect.*;
public class PrimeFinder {
static Predicate<Integer> isPrimeToTenThousand = new Predicate<Integer>() {
private boolean[] primes = new boolean[10000];
{
// prime detection algorithm from
// http://www.mkyong.com/java/how-to-determine-a-prime-number-in-java/
// will contain true or false values for the first 10,000 integers
Arrays.fill(primes, true); // assume all integers are prime.
primes[0] = primes[1] = false; // we know 0 and 1 are not prime.
for (int i = 2; i < primes.length; i++) {
// if the number is prime,
// then go through all its multiples and make their values false.
if (!primes[i]) continue;
for (int j = 2; i * j < primes.length; j++)
primes[i * j] = false;
}
}
@Override
public boolean apply(Integer number) {
return primes[number];
}
};
public static void main(String args[]) {
ImmutableSortedSet<Integer> positiveIntegersTo100 = Ranges.open(1, 100).asSet(DiscreteDomains.integers());
Iterable<Integer> primeNumbersTo100 = Iterables.filter(positiveIntegersTo100, isPrimeToTenThousand);
// output: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
System.out.println(primeNumbersTo100);
}
}
最后,关于如何模拟Python list comprehensions in Java的其他问题及其答案应该会有所帮助。