我已经开始使用Java 8并尝试将某些流转换为增强循环。
因此,例如,我正在尝试将此流转换为for循环,但是我做得不正确:
List<Job> jobs = shipment.getJobs();
Job shoppingJob = jobs.stream().filter(job -> job.isShopping()).findFirst().orElse(null);
Job deliveryJob = jobs.stream().filter(job -> job.isDelivery() || job.isRanger()).findFirst().orElse(null);
我想知道是否可以将上述示例转换为增强的for循环。到目前为止,我尝试像这样转换我的for循环代码:
List<Job> jobs = shipment.getJobs();
Job shoppingJob = null;
Job deliveryJob = null;
Job rangerJob = null;
if(jobs != null || jobs.isEmpty()) {
for (Job job : jobs) {
if (job.isShopping()) {
shoppingJob = job;
} else {
if (job.isDelivery()) {
deliveryJob = job;
}
}
}
}
答案 0 :(得分:2)
您应将break
用于findFirst
功能。
下面是发现shoppingJob
破损的情况。
Job shoppingJob = null;
if (jobs != null || jobs.isEmpty()) {
for (Job job : jobs) {
if (job.isShopping()) {
shoppingJob = job;
break;
}
}
}
下面是发现deliveryJob
破损
Job deliveryJob = null;
if (jobs != null || jobs.isEmpty()) {
for (Job job : jobs) {
if (job.isShopping() || job.isRanger()) {
deliveryJob = job;
break;
}
}
}
但是您想要找到一个foor loop
,您也可以这样做;
if (jobs != null || jobs.isEmpty()) {
for (Job job : jobs) {
if (!shoppingJobFound && job.isShopping()) {
shoppingJob = job;
shoppingJobFound = true;
}
if (!deliveryJobFound && (job.isDelivery() || job.isRanger())) {
deliveryJob = job;
deliveryJobFound = true;
}
if (shoppingJobFound && deliveryJobFound) {
break;
}
}
}
答案 1 :(得分:1)
findFirst
的意义在于,Stream
管道将仅评估Stream
的元素,直到找到第一个匹配元素(通过过滤器)为止。
将其转换为for循环时,一旦找到匹配项,就应退出循环。但是,由于要将两个Stream
流水线转换为单个for循环,因此只有在找到两个条件都匹配后,才应该中断循环。
List<Job> jobs = shipment.getJobs();
Job shoppingJob = null;
Job deliveryJob = null;
if (jobs != null) {
for (Job job : jobs) {
if (shoppingJob == null && job.isShopping()) { // this is the first shopping job
shoppingJob = job;
if (deliveryJob != null) { // we can break after finding a match for both conditions
break;
}
}
if (deliveryJob == null && (job.isDelivery() || job.isRanger())) { // this is the first delivery or range job
deliveryJob = job;
if (shoppingJob != null) { // we can break after finding a match for both conditions
break;
}
}
}
}
答案 2 :(得分:1)
我看到您发布的代码有几个问题。这是应该执行的代码
if(jobs != null) {
for (Job job : jobs) {
if (shoppingJob == null && job.isShopping()) {
shoppingJob = job;
}
else if (deliveryJob == null && (job.isDelivery() || job.isRanger())) {
deliveryJob = job;
}
}
}
所以需要改变的东西:
1)。如果作业列表为NullPointerException
,则第一个if条件的第二部分将引发null
。你有
if(jobs != null || jobs.isEmpty()) {
翻译为:如果不是null
的工作进入该区块,或者如果null
是工作,则在isEmpty()
上调用jobs
(然后调用{{1} isEmpty()
上的}将引发null
)。正如您在评论中指出的,NullPointerException
也是多余的。
相反,我认为这就是您所需要的
isEmpty()
2)。如果要从流代码中获得与 if(jobs != null) {
相同的值,则必须确保一次为变量shoppingJob
和deliveryJob
赋值后,它们不会被覆盖。 。
否则,如果列表中有一个以上的购物任务或一个以上的交付任务,则这些变量实际上将最终分配给列表中的最后一个匹配任务,而不是第一个。这就是为什么需要这些条件的第一部分,即在本示例中为findFirst()
位
shoppingJob == null
3)。无需在else子句中编写if嵌套,如果需要条件else语句,则可以只使用if (shoppingJob == null && job.isShopping()) {
。尽管在这种情况下,为了完全符合逻辑,您根本不应该使用else if
(在原始Streams代码中,如果作业为else
和isShopping
返回了true,则相同作业可以分配给两个变量,但是如果您在此处使用else,则只能分配给一个变量)
所以代替这个
isDelivery
您可以只使用if语句(没有其他内容)
else {
if (deliveryJob == null && (job.isDelivery() || job.isRanger())) {
4)。最后,在原始代码中,您尝试复制,if (deliveryJob == null && (job.isDelivery() || job.isRanger())) {
被分配给为deliveryJob
或isDelivery()
返回true的作业。在for循环代码中,您只检查了isRanger()
希望有帮助。
答案 3 :(得分:0)
已解决。谢谢
我只需要在null
和shoppingJob
的每种条件下检查deliveryJob
。将会是:
List<Job> jobs = shipment.getJobs();
Job shoppingJob = null;
Job deliveryJob = null;
Job rangerJob = null;
for (Job job : jobs) {
if (shoppingJob == null && job.isShopping()) {
shoppingJob = job;
}
if (deliveryJob == null && (job.isDelivery())) {
deliveryJob = job;
}
}