我是Java 8 lambda和stream的新手。对于练习,我试图在可能的情况下将一些方法从学校项目“翻译”为lambdas / streams。 这是旧方法。
正如你所看到的,我需要给丢弃方法一个int,这是玩家手中第一张可玩牌的编号。
public Card autoPlay(Card flipped) {
for (int i = 0; i < super.getHand().size(); i++) {
if (super.getHand().get(i).isCompatible(flipped)) { //check if card from hand is compatible with flipped card (same number or color)
return (this.discard(i)); //remove from hand and returns it
}
}
return null; //if any compatible card found
}
到目前为止,我的方法的新版本是:
public Card newAutoPlay(Card flipped){
return super.getHand().stream().filter(card -> card.isCompatible(flipped)).findFirst().get();
}
我发现了如何获得第一个兼容的卡,但不知道如何获取它的索引...我读了关于IntStreams(并使用列表的大小作为范围),但我不明白如何使用在这种特殊情况下。
是否有可能实现我想要做的事情,或者这样做不是一个好主意?
编辑:在探索了这个问题后,在这种情况下使用流带来了太多的复杂性,并且没有足够的可读性来解决这个简单的问题。所以我选择了for循环。还有其他一些变化,但核心思想保持不变。谢谢大家的帮助。@Override
public String play(Uno unoGame) {
int i = 0;
boolean found = false;
for (i = 0; i < super.getHand().size() && !found; i++) {
found = super.getHand().get(i).isCompatible(unoGame.getFlippedCard());
}
return found ? "play " + i : "draw";
}
答案 0 :(得分:3)
我建议使用Java 8 lambdas对现有代码进行以下解决方案,这需要将discard(int index)
的签名更改为discard(Card card)
,假设Card
确实实现了equals(Object obj)
和hashCode()
:
public Card autoPlay(Card flipped) {
Optional<Card> card = getHand().stream()
.filter(flipped::isCompatible)
.findFirst();
card.ifPresent(this::discard);
return card.orElse(null);
}
private void discard(Card card) {
// your code removing the first matching card from your hand
}
您可以考虑将null
的签名更改为Card autoPlay(Card flipped)
,而不是返回Optional<Card> autoPlay(Card flipped)
。
答案 1 :(得分:1)
一个班轮:
IntStream.range(0,getHand()::size).filter(i -> super.getHand().get(i).isCompatible(flipped))
.mapToObj(Integer::new).findFirst().map(this::discard).orElse(null);
有必要mapToObj
,因为map
类型Optional
上的int
函数不存在。可悲的是,java缺乏原生支持对,这会使这不那么难看。他们可以“用索引流”。但请记住:Streams意味着无限,因此没有索引。