1

我正在创建某种过滤系统,它基于不同元素接受/产生相同类型的“上下文”。

例如,可以对过程进行建模:

{generate_numbers(1..100)} --> {is_prime} --> {输出}

上下文可以是一个简单的“HashMap”。generate_numbers创建将“x”设置为某个数字的is_prime上下文,使用此上下文,查找“x”并相应地放置“prime”=true/false。

优点:

  • 灵活性(易于扩展(HashMap))

缺点:

  • 无类型值被强制转换

将所有内容声明为“上下文”中的字段也是一种可行的方法,但是这样会牺牲易于扩展性(我可以忍受)


但是......情况有点复杂,因为这些转换器元素分散在应用程序的包中:

{generate_numbers(1..100)} --> {is_prime} --> {calc(f_1)} --> {输出}
{--------------- pkg_A ------} | {--------- pkg_B --------}

所以有些部分 pkg_A 做了一些工作,然后有些部分 pkg_B 部分处理上下文 --> 这就是为什么我想混合这两种方法


我提出了以下想法:

选项1

  • 假设我已将包含上下文 E 的基本 HashMap 命名为
  • 创建 E 的子类,其中一些条目出现在 getter/setter 可用的字段中
  • 在每个处理函数中将传入的参数转换为所需的类类型

亲:

  • 相对容易实现

缺点:

  • 应该与字段同步 HashMap 内容
  • 访问值的方法不止一种可能会导致混淆

选项 2

  • 创建一些进行铸造的“工具”类

亲:

  • 每个函数都没有子类的运行时强制转换

缺点:

  • 访问总是转换为 HashMap 访问
  • 每次读取一个字段时都会进行一次强制转换

选项 3

我完全错了,我应该以不同的方式解决问题

更新:

与“如何促进上下文类?” 我的意思是我怎样才能创建一个相对方便的上下文来承载应用程序正在处理的所有杂乱的东西,因为在当前的工作流程中,这些信息被控制逻辑模糊了

4

2 回答 2

1

我相信你应该切换到Scala :D。
Scala 是一种具有 OOP 设计的函数式语言,它运行在 Java 虚拟机上,支持您刚才提到的内容,并具有强大的模式匹配引擎。

另一种方法可能涉及在 Java 中模拟函数范式,这实际上是几天前我的想法,但是我有太多的工作并忘记了它:D。

基本上,我回想他们的是你应该有一个界面

public interface Functionalizable {
    public void map(Function f);
}

WhereFunction也将是一个接口,您可以扩展它来编写自己的函数。然后,一个这样的例子(可能很糟糕,但这是我在火车上上班时的想法)可能是这样的:

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

于 2012-07-14T10:54:28.853 回答
0

试图传递元数据会让人头疼。相反,您需要一个函数式编程解决方案,但特别是您似乎想要处理列表推导- 在您的示例中是generate_numbers函数。虽然您可以通过自己滚动来做到这一点 - 正如@Lopina 建议的那样 - 通过创建一组函数对象,我认为更好的路径是使用现有的 Java 库。

特别是 Google Guava有许多工具可以以这种方式处理 Java 集合 -功能习语就是您想要的。您必须编写自己的函数(在本例中为 Guava Predicates)才能在 Guava 的框架中使用,但我认为它为您描述的问题提供了正确的工具和抽象级别。我发现这个问题的答案特别有助于理解谓词

番石榴代码示例

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);
    }
}

最后,this other question及其关于如何在Java中模拟Python列表推导的答案应该会有所帮助。

于 2012-07-15T17:05:31.970 回答