Поток 2 зацикливается с использованием Java 8 и возвращает объект внешнего цикла из внутреннего цикла - PullRequest
1 голос
/ 30 октября 2019

У меня есть такая функция:

public static Xyz getXyz(P p) {
    if (p == null) {
        return null;
    }

    List<Object> bs = p.getB();
    if (CollectionUtils.isEmpty(Bs)) {
        return null;
    }
    for (Object b : bs) {
        if (b instanceof R) {
            R r = (R) b;
            List<Object> cObjects = r.getB();
            for (Object cObject : cObjects) {
                if (cObject instanceof C) {
                    C c = (C) cObject;
                    Object vObject = cObject.getV();
                    if (vObject instanceof V) {
                        return r.getXyz();
                    }
                }
            }
        }
    }
    return null;
}

Я хотел изменить код, используя потоки Java 8. Возможно ли это потому, что я возвращаю свойство из 1-го цикла внутри 2-го цикла.

Я пробовал эти 2 способа. Но это не помогает и кажется неправильным:

public static Xyz getXyz(P p) {
    if (p == null) {
        return null;
    }

    List<Object> bs = p.getB();
    if (CollectionUtils.isEmpty(Bs)) {
        return null;
    }

       Xyz xyz = null;
         bs.stream()
            .filter(b -> (b instanceof R))
            .map(b -> (R) b).forEach(r -> {
                    List<Object> cObjects = = r.getB();
                     Optional vOptional= cObjects.stream()
                        .filter(cObjects -> (cObjects instanceof C))
                        .map(cObjects -> ((C) cObjects).getV())
                        .filter(vObject -> (vObject instanceof V)).findFirst();
                     if(vOptional.isPresent()){
                         xyz =  r.getXyz();
                         return;
                     }
    });
        return xyz;
}

Я пробовал это, но я не думаю, что смогу собрать нужное мне значение

bs.stream()
    .filter(b -> (b instanceof R))
    .flatMap(b -> ((R) b).getB().stream())
    .filter(cObject -> (cObject instanceof C))
    .map(cObject -> ((C) cObject).getV())
    .filter(vObject -> (vObject instanceof V))
    .collect(/*no idea if I can collect the value I desire*/);

Использует поток плохая идеядля моего требования? Или я на неверном пути?

1 Ответ

5 голосов
/ 30 октября 2019

Попробуйте что-то вроде этого:

return bs.stream()
        .filter( b -> b instanceof R)
        .map(b -> (R) b)
        .flatMap(r -> r.getB().stream()
                .filter(cObject -> cObject instanceof C)
                .map(cObject -> ((C) cObject).getV())
                .filter(vObject -> vObject instanceof V)
                .map(v -> r.getXyz())
        ).findFirst().orElse(null);

ОБНОВЛЕНИЕ

Хольгер упомяните в комментарии, что было бы хорошо заменить flatMapс filter, так что вот более новая версия:

return bs.stream()
        .filter(b -> b instanceof R)
        .map(b -> (R) b)
        .filter(r -> r.getB()
                .stream()
                .anyMatch(c -> c instanceof C && ((C) c).getV() instanceof V)
        )
        .map(R::getXyz)
        .findFirst().orElse(null);
...