Java 8 - Streams嵌套ForEach与不同的集合 [英] Java 8 - Streams Nested ForEach with different Collection
问题描述
我尝试了解新的Java 8 Streams,我试图在Java 8 Streams中通过集合传递嵌套的foreach循环。
I try to understand the new Java 8 Streams and I tried for days to transfer nested foreach loops over collection in Java 8 Streams.
可以重构下面的嵌套foreach循环包括Java-8-Streams中的if条件?
Is it possible to refactor the following nested foreach loops including the if-conditions in Java-8-Streams?
如果是,它会是什么样子。
If yes what would it look like.
ArrayList<ClassInq> Inq = new ArrayList<>();
TreeMap<String, SalesQuot> Quotations = new TreeMap<>();
ArrayList<ClassInq> tempInqAndQuot = new ArrayList<>();
ArrayList<SalesQuot> tempQuotPos = new ArrayList<>();
for (ClassInq simInq : this.Inq){
if (!simInq.isClosed() && !simInq.isDenied()){
for (Map.Entry<String, SalesQuot> Quot: Quotations.entrySet()){
SalesQuot sapQuot = Quot.getValue();
if (sapQuot.getInquiryDocumentNumber().compareTo(simInq.getSapInquiryNumber()) == 0){
simInq.setSAPQuotationNumber(sapQuot.getQuotationDocumentNumber());
tempInqAndQuot.add(simInq);
for (Map.Entry<String, SalesQuotPosition> quotp : sapQuot.getPosition().entrySet()){
tempQuotPos.add(quotp.getValue());
}
}
}
}
}
$ b b
非常感谢您的帮助。
Thanks a lot for your help.
BR
推荐答案
首先,尝试遵守Java命名约定,因为您的大写变量名称使它很难读取您的代码。第二,你想要了解 Stream
API是一件好事,但是你不应该忽略Java 8之前的基础 Collection
API。
First, try to adhere to the Java naming conventions, as your upper case variable names make it really hard to read your code. Second, it’s a good thing that you want to learn about Stream
API but you should not ignore the basics of the pre-Java 8 Collection
APIs.
当您只想查询 entrySet()
键或值。
It’s not useful to iterate over an entrySet()
when you are only interested in either, keys or values. You do it two times within a small piece of code.
第一次出现时,您可以替换
At the first appearance you can replace
for (Map.Entry<String, SalesQuot> Quot: Quotations.entrySet()){
SalesQuot sapQuot = Quot.getValue();
for (SalesQuot sapQuot: Quotations.values()){
(Map.Entry< String,SalesQuotPosition> quotp:sapQuot.getPosition()。entrySet()){...}的整个
At the second, the entire
for(Map.Entry<String,SalesQuotPosition> quotp: sapQuot.getPosition().entrySet()){
tempQuotPos.add(quotp.getValue());
}
可以替换为
tempQuotPos.addAll(sapQuot.getPosition().values());
因此,即使没有流,您的代码可以简化为
Thus even without streams, your code can be simplified to
for (ClassInq simInq : this.Inq){
if (!simInq.isClosed() && !simInq.isDenied()){
for (SalesQuot sapQuot: Quotations.values()){
if (sapQuot.getInquiryDocumentNumber().compareTo(simInq.getSapInquiryNumber()) == 0){
simInq.setSAPQuotationNumber(sapQuot.getQuotationDocumentNumber());
tempInqAndQuot.add(simInq);
tempQuotPos.addAll(sapQuot.getPosition().values());
}
}
}
}
它仍然不清楚它应该做什么和它是否正确。除了在您的问题的注释中指定的错误和怀疑之外,修改传入值(特别是从外层循环)看起来不正确。
though it’s still not clear what it is supposed to do and whether it’s correct. Besides the errors and suspicions named in the comments to your question, modifying the incoming values (esp. from the outer loop) does not look right.
这也不清楚为什么您正在使用 ... .compareTo(...)== 0
,而不是等于
。
It’s also not clear why you are using ….compareTo(…)==0
rather than equals
.
但是,它可以直接重写为使用流而不改变任何代码的逻辑:
However, it can be straight-forwardly rewritten to use streams without changing any of the code’s logic:
this.Inq.stream().filter(simInq -> !simInq.isClosed() && !simInq.isDenied())
.forEach(simInq -> Quotations.values().stream().filter(sapQuot ->
sapQuot.getInquiryDocumentNumber().compareTo(simInq.getSapInquiryNumber())==0)
.forEach(sapQuot -> {
simInq.setSAPQuotationNumber(sapQuot.getQuotationDocumentNumber());
tempInqAndQuot.add(simInq);
tempQuotPos.addAll(sapQuot.getPosition().values());
})
);
仍然,我建议先清理原来的逻辑,然后重写它以使用其他API。流形式将从更精确地定义要实现的内容中受益。
Still, I recommend cleaning up the original logic first before rewriting it for using other APIs. The stream form would greatly benefit from a more precise definition of what to achieve.
这篇关于Java 8 - Streams嵌套ForEach与不同的集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!