Как отфильтровать данные в списке по нескольким параметрам в Java? - PullRequest
0 голосов
/ 02 февраля 2019

У меня есть список GroupOffices

List<GroupOffice> officesOfTheGroup;

Я хочу выяснить, не равен ли идентификатор groupOffice.getId (длинное значение), нометка groupOffice.getLabel (String) и присвоить его логическому значению.Приведенный ниже код работает хорошо, но есть ли лучший подход вместо прохождения всех пунктов с циклом for?

 public GroupOfficeDto saveGroupOffice(GroupOfficeDto groupOfficeDto) {     
            List<GroupOffice> officesOfTheGroup = //some list from db..
            for (GroupOffice go : officesOfTheGroup) {
                if ((!go.getId().equals(groupOfficeDto.getId())) && go.getLabel().equals(groupOfficeDto.getLabel())) {
                    return groupOfficeDto;
                }
        return null:
}

Или как использовать поток?Если да, то лучше ли использовать потоковый режим?

Примечание: Я использую Java8

Ответы [ 3 ]

0 голосов
/ 02 февраля 2019

Если вам нужно логическое значение, вы можете сделать:

boolean b = officesOfTheGroup.stream()
    .anyMatch(office -> !office.getId().equals(5) && office.getLabel().equals("London"))
0 голосов
/ 02 февраля 2019

есть ли лучший подход вместо того, чтобы проходить все пункты с циклом for? 1003 *

Примечательно, что ваш код не проходит все пункты, еслион находит приемлемый прежде, чем достигнет конца списка.Но если у вас есть только список для работы, тогда нет альтернативы тому, чтобы быть готовым проверить каждый элемент списка.Что касается использования цикла for, я думаю, что это нормально.

Или как я могу использовать поток?Если да, то лучше ли использовать потоковую передачу?

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

public GroupOfficeDto saveGroupOffice(GroupOfficeDto groupOfficeDto) {     
    List<GroupOffice> officesOfTheGroup = //some list from db..
    Integer officeId = groupOfficeDto.getId();
    String officeLabel = groupOfficeDto.getLabel();

    return officesOfTheGroup.stream()
            .filter(o -> !o.getId().equals(officeId))
            .anyMatch(o -> o.getLabel().equals(officeLabel))
        ? groupOfficeDto : null;
}

Особенно уместным здесь является использование терминальной операции .anyMatch(), поскольку она позволяет завершить потоковую обработку, как только будет определен результат, как ваш цикл forвместо обработки всего потока.Также обратите внимание, что идентификатор и метка, с которыми вы сравниваете офисы, извлекаются и сохраняются в переменных перед выражением потока.Это позволяет им быть «эффективно окончательными», поскольку им необходимо появляться в лямбдах в потоке.Это также немного более эффективно сделать так, вместо того, чтобы снова и снова извлекать одни и те же объекты из DTO - для случая цикла for.

Обратите внимание, что потоковая версия ненамного проще, чем версия цикла, и не намного проще для чтения.Лично я не вижу большого преимущества ни для одного, ни для другого.

0 голосов
/ 02 февраля 2019

Попробуйте это:

public GroupOfficeDto saveGroupOffice(GroupOfficeDto groupOfficeDto) {
    ...     
    List<GroupOffice> result = officesOfTheGroup.stream()
        .filter(it -> it.getLabel().equals(groupOfficeDto.getLabel()))
        .filter(it -> !it.getId().equals(groupOfficeDto.getId()))
        .collect(Collectors.toList())
    ...
}
...