是否有一种很好的方法将此Java功能转换为递归,可扩展的[lambda]函数

发布于 2025-01-25 21:37:59 字数 1491 浏览 4 评论 0 原文

我写了一个功能,我认为这是递归lambda功能的巨大潜力,但我只是无法围绕如何自己实施它来缠绕。我要将其转换为递归lambda函数的原因是,只要我想要,我就可以将其运行,而我必须像目前必须复制粘贴的另一个代码。

    private void crack()
    {
        System.out.println("Trying 1 mangle");
        wordList.forEach(
                x -> Mangle.getAllMangles(x).forEach(this::checkAllVictims)
        );
        System.out.println("Trying 2 mangles");
        wordList.forEach(
                x -> Mangle.getAllMangles(x).forEach(
                        y -> Mangle.getAllMangles(y).forEach(this::checkAllVictims)
                )
        );
        System.out.println("Trying 3 mangles");
        wordList.forEach(
                x -> Mangle.getAllMangles(x).forEach(
                        y -> Mangle.getAllMangles(y).forEach(
                                z -> Mangle.getAllMangles(z).forEach(this::checkAllVictims)
                        )
                )
        );
    }

最好的方法如何重构此功能?

从一年前与Elixir的功能编程课程中,我做了类似的事情,但我不知道如何在此处应用相同的原则。

def to_church(0) do
    fn(_), y -> y end
end
def to_church(n) do
    fn(f, x) -> f.(to_church(n - 1).(f, x)) end
end

可以找到整个长生不老药如果需要更多上下文。

我遇到的另一个问题,不是这个问题的主要问题,而是最重要的樱桃,是在同时运行上述代码作为executorService线程池中可运行对象的一部分时(run(run())调用crack())除了第一个分配的停止在打印“尝试1 mangle”之后执行的所有线程。他们只是在没有痕迹的情况下消失了,我不知道为什么。

I have written a function which I see great potential in being a recursive lambda function but I just can't wrap my head around how to implement it myself. The reason why I want to convert it to a recursive lambda function is the ability for me to run it for as long as I want where as currently I would have to copy paste another segment of code.

    private void crack()
    {
        System.out.println("Trying 1 mangle");
        wordList.forEach(
                x -> Mangle.getAllMangles(x).forEach(this::checkAllVictims)
        );
        System.out.println("Trying 2 mangles");
        wordList.forEach(
                x -> Mangle.getAllMangles(x).forEach(
                        y -> Mangle.getAllMangles(y).forEach(this::checkAllVictims)
                )
        );
        System.out.println("Trying 3 mangles");
        wordList.forEach(
                x -> Mangle.getAllMangles(x).forEach(
                        y -> Mangle.getAllMangles(y).forEach(
                                z -> Mangle.getAllMangles(z).forEach(this::checkAllVictims)
                        )
                )
        );
    }

How would one go about refactoring this function the best way possible?

From a course on functional programming with Elixir a year ago I did something similar but I do not know how to apply the same principle here.

def to_church(0) do
    fn(_), y -> y end
end
def to_church(n) do
    fn(f, x) -> f.(to_church(n - 1).(f, x)) end
end

The whole Elixir code can be found here if more context is needed.

Another issue I have had, which is not the main issue of this question but would be a cherry on top to have answered, is that when running the above code in parallel as part of a Runnable object in an ExecutorService thread pool (run() calls crack()) all the threads except the first one allocated stops executing after printing "Trying 1 mangle". They simply just dissapear without a trace and I do not know why.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

若水般的淡然安静女子 2025-02-01 21:37:59

我想出了一些解决方案。

我创建了一个新的类,该类实现了Biconsumer< list; integer>。

public Mangler(final Cracker c)
{
    this.c = c;
}

public void start(String s, int i)
{
    accept(Mangle.getAllMangles(s), i - 1); 
}

@Override
public void accept(List<String> strings, Integer integer)
{
    if (integer == 0) {
        strings.forEach(x -> c.checkAllVictims(x));
        return;
    }
    strings.forEach(x -> this.accept(Mangle.getAllMangles(x), integer - 1));
}

然后,我可以在cracker类的crack()函数中调用它:

Mangler m = new Mangler(this);
dictionary.parallelStream().forEach(word -> m.start(word, 1));
dictionary.parallelStream().forEach(word -> m.start(word, 2));
dictionary.parallelStream().forEach(word -> m.start(word, 3));

我还更改了并行性,仅适用于饼干的字典,而不是使整个类都可以运行。

I came up with somewhat of a solution.

I created a new class which implemented BiConsumer<List, Integer>.

public Mangler(final Cracker c)
{
    this.c = c;
}

public void start(String s, int i)
{
    accept(Mangle.getAllMangles(s), i - 1); 
}

@Override
public void accept(List<String> strings, Integer integer)
{
    if (integer == 0) {
        strings.forEach(x -> c.checkAllVictims(x));
        return;
    }
    strings.forEach(x -> this.accept(Mangle.getAllMangles(x), integer - 1));
}

Which I could then call in the crack() function of my Cracker class:

Mangler m = new Mangler(this);
dictionary.parallelStream().forEach(word -> m.start(word, 1));
dictionary.parallelStream().forEach(word -> m.start(word, 2));
dictionary.parallelStream().forEach(word -> m.start(word, 3));

I also changed the parallelism to apply only to the dictionary of the Cracker instead of making the whole class a Runnable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文