如果有人能想出更好的方式来表达它,我会很感激标题的编辑。
我有一个代表具有容量的集合的类。
我的代码是
public class PlayerParty implements Party {
public PlayerParty() {
this(Collections.emptyList());
}
public PlayerParty(Collection<Pokemon> pokemon) {
Objects.requireNonNull(pokemon, "pokemon must not be null");
if (pokemon.size() > PARTY_LIMIT) {
throw new IllegalArgumentException(String.format(PARTY_LIMIT_EXCEEDED, PARTY_LIMIT));
}
createPartySlots();
fillPartySlots(pokemon);
}
@Override
public final Iterable<Pokemon> getPokemon() {
return Collections.unmodifiableCollection(
partySlots
.stream()
.filter(PartySlot::isFull)
.map(PartySlot::getPokemon)
.collect(Collectors.toList()));
}
public final Optional<PartySlot> getNextSlot() {
return partySlots
.stream()
.filter(slot -> !slot.isFull())
.findFirst();
}
private void createPartySlots() {
for (int i = 0; i < PARTY_LIMIT; i++) {
partySlots.add(new PartySlot());
}
}
private void fillPartySlots(Iterable<Pokemon> pokemon) {
pokemon.forEach(p -> {
// Since we just added all of the slots, they're
// guaranteed to be present
// noinspection OptionalGetWithoutIsPresent
PartySlot slot = getNextSlot().get();
slot.fill(p);
partySlots.add(slot);
});
}
private static final String PARTY_LIMIT_EXCEEDED = "party cannot have more than %s Pokemon";
private static final int PARTY_LIMIT = 6;
private final List<PartySlot> partySlots = new ArrayList<>();
}
有问题的方法围绕fillPartySlots
。
在PartySlot slot = getNextSlot().get();
行上,我收到一条警告,提示我在没有先致电get
的情况下致电isPresent
。这是可以理解的,因为通常我想在尝试从Optional
中获取值之前这样做。
是否有更好的方法可以根据另一个流的状态对一个流执行操作?也就是说,我可以更改它以便它使用isPresent
(在此方法中应始终为true,因为构造函数中的先前调用会创建它们)?我可以做点什么吗
partySlots
.stream()
.filter(slot -> !slot.isFull()) // should return true for all slots
.forEach(slot -> {
slot.fill(nextAvailableOneFromMethodParameter?);
});
答案 0 :(得分:2)
如果缺少值的情况表示错误,则可以在不检查.get()
的情况下调用.isPresent()
。如果该值不存在,.get()
将以NoSuchElementException
快速失败,这是您可能想要的。
您可能希望使用.orElseThrow(...)
代替.get()
在代码中更清楚地记录,但这是首选问题。
另一方面,您使用.filter(slot -> !slot.isFull())
的建议代码将默默地忽略插槽已满的情况,并使此类错误更难找到。此外,替代实现在插槽上迭代而不是在提供的小精灵上进行迭代,但如果口袋妖怪少于插槽那么会怎样呢?
顺便说一句,你有充分的理由使用Iterable
吗? Collection
或List
可能是更合适的选择。考虑将此帖子发布到code review。