![](/img/trans.png)
[英]How do I iterate through two streams using java 8 lambda expressions and keeping a count
[英]How can I rewrite this method using streams and lambda expressions?
我这里有这段代码基本上只是创建了一些等于参数的线程,在每个线程中实例化一个 MyRunnable object,将线程添加到线程列表,然后根据迭代设置线程的名称循环。
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 中?
Lambda 在可变局部变量、控制流和检查异常方面是不透明的。
那真的很糟糕……如果保证 lambda 表达式“在您使用它们时”运行。 如果您将 lambda 传递给其他线程或上下文以在完全不同的时间运行,那就太好了。 这解释了为什么lambda 在这 3 个方面不透明:如果 lambda 在它们被设计为能够执行的上下文之外运行,那就太棒了。
因此,当你使用它们的工作保证在上下文中运行时,lambdas 很糟糕。 有时它们是较小的邪恶,在这种情况下仍然值得运行它们,但是,所有其他条件都相同吗? Lambda 坏了。
那么,为什么您可能会对将这个极其简单的代码编写为 lambda 感兴趣? 你只会让事情变得更糟。
但是,如果你想忽略所有这些,将你的工具箱缩减为一个锤子(lambdas/stream API),然后将它用于所有事情,即使锤子并不是真正设计用于:
threads = IntStream.of(0, number)
.mapToObj(i -> new Thread(new MyRunnable(), "thread" + i))
.toList();
请注意,您编写MyRunnable::new
不是您想要的。
MyRunnable::new
构造了一个全新的class (不是你的MyRunnable!),它实现了 Runnable 并且其run()
方法执行以下操作:
我很怀疑你想要那个。 只是new MyRunnable()
将..创建一个新的 myrunnable。 哪个是你想要的,不是吗?
我只是这样做:
for (int i = 0; i < number; i++) {
list.add(new Thread(new MyRunnable(), "thread" + i));
}
更短,更容易理解,对未来的变化更灵活(例如:如果你改变了一些东西并且你从那里抛出一些检查过的异常,那没问题。而对于 lambda 表格你必须把它扔进垃圾箱并且重新开始。甚至:除了创建新线程 object 之外,您还想记录一些内容 - 在 lambda 版本中,您需要添加大括号,通常 go 到结构上的城镇。而对于第二个片段,只需...添加日志语句。根本不需要其他更改)。
你可以这样做:
public class ThreadManager {
protected List<Thread> threads;
public void createThreads(int number) {
IntStream.range(0, number).forEach(i -> threads.add(new Thread(MyRunnable::new, "thread" + i)));
}
}
IntStream.range()创建 stream,其行为类似于您的循环。 引用 - Returns a sequential ordered IntStream from startInclusive (inclusive) to endExclusive (exclusive) by an incremental step of 1.
.. 代码当然更短,但我非常怀疑它会更干净。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.