Wenn jemand kann eine bessere Möglichkeit, es zu Wort, würde ich mich über eine Bearbeitung für den Titel freuen.Was ist ein besserer Weg, um durch zwei Streams zu iterieren und Anwendung auf eine
Ich habe eine Klasse, die eine Sammlung mit einer Kapazität darstellt.
Der Code, den ich habe, ist
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<>();
}
Verfahren in Frage um fillPartySlots
dreht.
Auf der Leitung PartySlot slot = getNextSlot().get();
, bekomme ich eine Warnung, die ich anrufe get
ohne einen Anruf an isPresent
zuerst. Dies ist verständlich, denn normalerweise würde ich das tun wollen, bevor ich versuche, einen Wert aus dem Optional
herauszuholen.
Gibt es eine bessere Möglichkeit, eine Operation in einem Stream auszuführen, basierend auf dem Status eines anderen Streams? Nämlich, kann ich das ändern, so dass es isPresent
verwendet (was immer in dieser Methode wahr sein sollte, weil der vorherige Aufruf im Konstruktor sie erstellt)? Kann ich etwas tun, wie
partySlots
.stream()
.filter(slot -> !slot.isFull()) // should return true for all slots
.forEach(slot -> {
slot.fill(nextAvailableOneFromMethodParameter?);
});
Wenn es weniger Pokemon gibt als Slots, dann sind Slots ohne einen in Ordnung. Die Idee ist, maximal 6 Slots zu haben. Ein Minimum von 1 Slot muss ausgefüllt werden. So könnte man 3 Pokemon und die Kapazität 3 weitere haben. – Zymus
Richtig, also, wenn Sie ein '.forEach' auf den Slots tun und versuchen, sie aus dem' Iterable 'zu füllen, müssen Sie diesen Fall behandeln. –
Misha
Das war ein Teil der Frage; wie ich gleichzeitig über beide gleichzeitig iterieren könnte, und füge jedes aus dem 'Iterable' zu den Slots hinzu. – Zymus