当前位置: 首页 > 知识库问答 >
问题:

如何使用streams和lambda表达式重写此方法?

涂承运
2023-03-14

我在这里有一段代码,基本上只是创建一个等于参数的线程数,在每个线程中实例化一个MyRunnable对象,将线程添加到线程列表中,然后根据for循环的迭代设置线程的名称。

public class ThreadManager {
    protected List<Thread> threads;

    public void createThreads(int number) {
        
        for (int i = 0; i < number; i++) {
            Thread thread = new Thread(MyRunnable::new);
            threads.add(thread);
            thread.setName("thread"+i);
        }
    }
}

我的问题是,有没有更干净的方法?是否可以使用流将此功能封装在lambda中?

共有2个答案

班承恩
2023-03-14

你可以这样做:

public class ThreadManager {

  protected List<Thread> threads;

  public void createThreads(int number) {
    IntStream.range(0, number + 1).forEach(i -> threads.add(new Thread(MyRunnable::new, "thread" + i)));
  }
}

intStream.range()创建流,其行为类似于您的循环。引用-以1.的增量步骤返回一个顺序有序的intStream,从开始包含(包括)到结束排除(排除)。代码当然更短,但我非常怀疑它会更干净。

糜帅
2023-03-14

lambda在可变局部变量、控制流和检查异常方面是不透明的。

这真的很糟糕...如果lambdas保证在你使用它们的时候运行。如果你把lambdas交给其他线程或上下文在完全不同的时间运行,那就太好了。这解释了为什么lambdas在这三个方面不透明:如果lambda在上下文之外运行,那就太棒了,因为它们被设计成能够这样做。

因此,当使用它们的作业保证在上下文中运行时,lambdas就不好了。有时,它们是较小的邪恶,在这种情况下,运行它们仍然是值得的,但是,所有其他事情都是平等的吗?Lambda很糟糕。

那么,为什么您可能有兴趣为lambdas编写这个极其简单的代码呢?你只会让事情变得更糟。

但是,如果你想忽略所有这些,把你的工具箱简化成一个锤子(lambdas/stream API),从而把它用于所有事情,甚至锤子不是真正设计用来做的事情:

threads = IntStream.of(0, number)
  .mapToObj(i -> new Thread(new MyRunnable(), "thread" + i))
  .toList();

请注意,您编写的MyRunnable::new不是您想要的。

MyRunnable::新的构造了一个全新的类(不是你的MyRunnable!),它实现了Runnable,其run()方法做到了:

  • 创建MyRunnable的新html" target="_blank">实例

我很怀疑你想要那样。只需new MyRunnable()will。。做一个新的myrunnable。这就是你想要的,不是吗?

我会这样做:

for (int i = 0; i < number; i++) {
  list.add(new Thread(new MyRunnable(), "thread" + i));
}

更短,更容易理解,更灵活地适应未来的变化(例如:如果你改变了一些东西,并且从里面抛出了一些检查过的异常,这没有问题。但是对于lambda表单,你必须把它扔进垃圾箱重新开始。甚至:除了创建一个新的thread对象之外,你还想记录一些东西——在lambda版本中,你需要添加大括号,一般来说,你需要在结构上找到它。而对于第二个片段,只需要。…添加日志语句。无需任何其他更改)。

 类似资料:
  • 今天在编程课上我们从streams和Lambda开始,我要做一个练习。 第一个任务是编写一个方法,计算列表中偶数的平均值。我已经编写了这段代码,但显然我没有使用流。 编辑解决方案: 第二个任务是编写一个方法,选择所有以“a”(不区分大小写)开头或有3个字符的字符串,并将其更改为大写。我的代码: 编辑:解决方案: 最后一个任务是返回列表,但将“g”添加到偶数,将“u”添加到奇数。我的代码: 编辑:解

  • 嗨,我有一个代码块,它将一种窗口对象的列表转换为另一种,并将其填充到一个地图中,由ID键控。可能有许多具有相同id但具有不同名称和属性的对象实例。我所做的是做一个列表[W1(1,2,3),W1(2,3,4),W2(1,3,4)...]并将其转换为映射[键W1,值(1,2,3),(2,3,4)键W2,....] 我想知道我是否可以使用流和lambdas来崩溃这个。 list.stream().col

  • 问题内容: 假设我有一个通用接口: 和方法sort: 我可以调用此方法并将lambda表达式作为参数传递: 那会很好的。 但是现在,如果我将接口设为非泛型,并且将方法设为泛型: 然后像这样调用: 它不会编译。它在lambda表达式中显示错误: “目标方法是通用的” 好的,当我使用编译时,它显示以下错误: 从此错误消息看来,编译器似乎无法推断类型参数。是这样吗 如果是,那为什么会这样呢? 我尝试了各

  • 好的,所以方法重载是一件坏事™。既然这个问题已经解决了,让我们假设我实际上想重载一个像这样的方法: 在Java7中,我可以很容易地使用不明确的匿名类作为参数来调用它们: 但这不能编译。编译器(javac,JDK1.8.0_05)不喜欢这样: 对我来说,直觉上,这没有意义。在产生返回值(“value-compatible”)的lambda表达式和产生(“void-compatible”)的lambd

  • 目前我学习Springboot。 在这个代码中 我知道这是lambda表达式,但我没有得到原始代码。这不是我的代码。你能让我知道原始代码吗?