Необязательный / Stream 2-й фильтр, если 1-й фильтр приводит к Optional.empty () - PullRequest
1 голос
/ 17 июня 2020

У меня есть метод, который я хотел бы изменить:

public Optional<Package> getPackage(String holderID, String packageID){
    Holder holder = service.getHolder(holderID);
    return holder.getPackages().stream()
            .filter(model-> StringUtils.equalsIgnoreCase(packageID,model.getPackageId())).findAny();
}

У держателя есть поле:

List<Package> packages;

В пакете есть поля:

String packageId;
String packageType;

I Меня интересует расширение метода, чтобы он выполнял дополнительный фильтр, если первый приводит к пустому Optional. Есть ли способ фильтровать по packageId, как указано выше, а затем фильтровать по packageType (например, packageType == "type1"), когда первый фильтр приводит к пустому необязательному параметру?

Думаю, в целом я Хотите знать, доступен ли фильтр только в том случае, если он приводит к непустому варианту Optional или Stream ?

Есть ли лучший способ сделать это, чем этот:

public Optional<Package> getPackage(String holderID, String packageID){
    Holder holder = service.getHolder(holderID);
    Optional<Package> package = holder.getPackages().stream()
            .filter(model-> StringUtils.equalsIgnoreCase(packageID,model.getPackageId())).findAny();
    if(package.isEmpty()){
        package = holder.getPackages().stream()
                .filter(model -> StringUtils.equalsIgnoreCase("type1",model.getPackageType()))
                .findAny();
    }
    return package;
}

Ответы [ 2 ]

3 голосов
/ 17 июня 2020

Вы можете использовать Optional.or() (доступно с Java 9), которому вы можете передать Supplier, который возвращает другой Optional:

holder.getPackages().stream()
      .filter(model-> StringUtils.equalsIgnoreCase(packageID,model.getPackageId())).findAny()
      .or(() -> holder.getPackages().stream()
            .filter(model -> StringUtils.equalsIgnoreCase("type1",model.getPackageType()))
            .findAny())
0 голосов
/ 18 июня 2020

Это можно сделать более общим способом для более чем двух случаев (но в этом случае это будет сложнее). С потоком Predicate вы можете указать столько условий, сколько вам нужно.:

Stream<Predicate<Package>> predicates = Stream.of(
        model-> StringUtils.equalsIgnoreCase(packageID,model.getPackageId()),
        model -> StringUtils.equalsIgnoreCase("type1",model.getPackageType())
);
Optional<Package> packageOptional = predicates
        .map(p -> holder.getPackages().stream().filter(p::test).findAny())
        .filter(Optional::isPresent).map(Optional::get)
        .findAny();

Он будет искать первый findAny для данного предиктора. В противном случае он вернет пустой Необязательный

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...