我有以下课程:
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]]
是否存在允许执行此操作的单行语句(使用流或任何第三方库)?
答案 0 :(得分:4)
虽然没有单个流操作,但
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());
答案 1 :(得分:2)
是否存在单行语句(使用流或任何第三方) 库)允许这样做吗?
两次执行操作,将更具可读性。
1)计算Standard
类型商品的最便宜价格:
Optional<Offer> minPriceOffer =
offers.stream()
.filter(o -> o.getType() == OfferType.STANDARD)
.min(Comparator.comparing(Offer::getPrice));
2)在收集的清单中排除此价格的Standard
个出价:
List<Offer> offersFiltered =
offers.stream()
.filter(o -> {
if (o.getType() == OfferType.STANDARD
&& !o.getPrice().equals(minPriceOffer.get().getPrice()))
return false;
// else
return true;
}
)
.collect(toList();
答案 2 :(得分:2)
以下是两个流:
standard
个要约,对其进行排序,并将其限制为1个元素(按价格最小)代码如下:
List<Offer> result = offers.stream()
.collect(Collectors.groupingBy(Offer::getType))
.entrySet()
.stream()
.flatMap(entry -> entry.getKey() == OfferType.STANDARD ?
entry.getValue().stream()
.sorted(Comparator.comparing(Offer::getPrice))
.limit(1)
: entry.getValue().stream())
.collect(Collectors.toList());
答案 3 :(得分:0)
List<Offer> result = offers.stream().filter(e -> OfferType.BONUS == e.getType()).collect(toList());
offers.stream().filter(e -> OfferType.STANDARD == e.getType()).findAny().ifPresent(result::add);