Как преобразовать поток в расширенный цикл - PullRequest
0 голосов
/ 25 сентября 2018

Я начал работать с 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 shopping job = null;
 Job delivery job = null;
 Job rangerJob = null;
    if(jobs != null || jobs.isEmpty()) {
        for (Job job: jobs) {
            if (job.isShopping()) {
                shoppingJob = job;
            } else {
                if (job.isDelivery()) {
                    deliveryJob = job;
                }
            }
        }
    }

Ответы [ 4 ]

0 голосов
/ 25 сентября 2018

решаемая.Спасибо

Мне просто нужно поставить 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;
        }
    }
0 голосов
/ 25 сентября 2018

Смысл 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;
            }
        }
    }
}
0 голосов
/ 25 сентября 2018

Я вижу несколько проблем с кодом, который вы разместили.Это код, который должен делать то, что вы ищете

    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).Вторая часть вашего самого первого условия if выдаст NullPointerException, если список заданий будет null.У вас было

if(jobs != null || jobs.isEmpty()) {

, что означает: если задания не null входят в блок, или если задания null, вызов isEmpty() на jobs (и вызов isEmpty() наnull бросит NullPointerException).isEmpty() также является избыточным, как вы указали в комментариях.

Вместо этого я думаю, что это все, что вам нужно

    if(jobs != null) {

2).Вы должны убедиться, что переменные shoppingJob и deliveryJob не будут перезаписаны после однократного присвоения значения, если вы хотите получить что-то эквивалентное findFirst() из кода Stream.

В противном случае, если в списке более одного задания на покупку или более одного задания на поставку, эти переменные в итоге будут назначены последнему подходящему заданию в списке, а не первому.Вот почему необходима первая часть этих условий, т.е. в этом примере shoppingJob == null бит

if (shoppingJob == null && job.isShopping()) {

3).Нет необходимости писать if, вложенный в предложение else, вы можете просто использовать else if, если вам нужен условный оператор else.Хотя в этом случае для точного соответствия логике не следует использовать else вообще (в исходном коде Streams, если задание вернуло значение true для isShopping и isDelivery, одно и то же задание может быть назначено обоимпеременные, но если вы используете здесь другое, которое может быть назначено только одному)

Таким образом, вместо этого

else {
          if (deliveryJob == null && (job.isDelivery() || job.isRanger())) {

Вы можете просто использовать оператор if (без else)

if (deliveryJob == null && (job.isDelivery() || job.isRanger())) {

4).Наконец, в исходном коде, который вы пытаетесь воспроизвести, deliveryJob было назначено заданию, которое вернуло true для isDelivery() или isRanger().В вашем цикле for вы проверяли только isDelivery()

Надеюсь, что это поможет.

0 голосов
/ 25 сентября 2018

Вы должны использовать 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;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...