1以外の条件を満たしたすべての要素をフィルタリングするためのストリームを適用します

pantuptus:

私は、次のクラスがあります。

public class Offer {

    private final OfferType type;
    private final BigDecimal price;

    // constructor, getters and setters
}

そして、列挙型:

public enum OfferType {
    STANDARD, BONUS;
}

私のユースケースは、入力としてオファーのリストを持つ、私は最も安いものを除くすべての標準的なものをフィルタリングしたいということです。したがって、次の入力データのための

List<Offer> offers = Arrays.asList(new Offer(OfferType.STANDARD, BigDecimal.valueOf(10.0)),
            new Offer(OfferType.STANDARD, BigDecimal.valueOf(20.0)),
            new Offer(OfferType.STANDARD, BigDecimal.valueOf(30.0)),
            new Offer(OfferType.BONUS, BigDecimal.valueOf(5.0)),
            new Offer(OfferType.BONUS, BigDecimal.valueOf(5.0)));

私は、次のような結果を期待します

[Offer [type=STANDARD, price=10.0], Offer [type=BONUS, price=5.0], Offer [type=BONUS, price=5.0]]

そうすることが可能になります(ストリームやサードパーティのライブラリを使用して)単一ラインステートメントはありますか?

ユージン:

していないが、単一のストリーム操作で:

List<Offer> some = offers.stream()
                         .filter(x -> x.getType() != OfferType.STANDARD)
                         .collect(Collectors.toCollection(ArrayList::new));

offers.stream()
      .filter(x -> x.getType() == OfferType.STANDARD)
      .min(Comparator.comparing(Offer::getPrice))
      .ifPresent(some::add);

あなた自身がこれをたくさんやって見つけた場合は、カスタムコレクタスピンすることがあります。

 public static Collector<Offer, ?, List<Offer>> minCollector() {
    class Acc {

        Offer min = null;
        List<Offer> result = new ArrayList<>();

        void add(Offer offer) {
            if (offer.getType() == OfferType.STANDARD) {
                if (min == null) {
                    min = offer;
                } else {
                    min = offer.getPrice()
                               .compareTo(min.getPrice()) > 0 ? min : offer;
                }
            } else {
                result.add(offer);
            }
        }

        Acc combine(Acc another) {
            this.min = reduceMin(this.min, another.min);
            result.addAll(another.result);
            return this;
        }

        List<Offer> finisher() {
            result.add(min);
            return result;
        }

        private Offer reduceMin(Offer left, Offer right) {
            return Collections.min(Arrays.asList(left, right),
                                   Comparator.nullsLast(Comparator.comparing(Offer::getPrice)));
        }
    }

    return Collector.of(Acc::new, Acc::add, Acc::combine, Acc::finisher);
}

そして、使用方法は、次のようになります。

List<Offer> result = offers.stream()
                           .collect(minCollector());

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=199353&siteId=1