If anyone can think of a better way to word it, I'd appreciate an edit for the title.
I have a class that represents a collection with a capacity.
The code I have is
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<>();
}
The method in question revolves around fillPartySlots
.
On the line PartySlot slot = getNextSlot().get();
, I get a warning indicating I'm calling get
without a call to isPresent
first. This is understandable, as typically I would want to do that before trying to get a value out of the Optional
.
Is there a better way to do perform an operation on one stream, based on the state of another stream? Namely, can I change this so that it uses isPresent
(which should always be true in this method because the previous call in the constructor creates them)? Could I do something like
partySlots
.stream()
.filter(slot -> !slot.isFull()) // should return true for all slots
.forEach(slot -> {
slot.fill(nextAvailableOneFromMethodParameter?);
});