gpt4 book ai didi

java - 在 Java 8 流中转换类型

转载 作者:搜寻专家 更新时间:2023-10-30 19:49:09 24 4
gpt4 key购买 nike

为了获得一些使用 Java 的新流的经验,我一直在开发一个处理扑克牌的框架。这是我的第一个版本代码,用于创建一个 Map,其中包含一手牌中每套花色的牌数(Suit 是一个 enum):

Map<Suit, Long> countBySuit = contents.stream() // contents is ArrayList<Card>  
.collect( Collectors.groupingBy( Card::getSuit, Collectors.counting() ));

效果很好,我很高兴。然后我重构,为“Suit Cards”和 Jokers 创建单独的 Card 子类。因此 getSuit() 方法从 Card 类移到了它的子类 SuitCard 中,因为 clown 没有西装。新代码:

Map<Suit, Long> countBySuit = contents.stream() // contents is ArrayList<Card>  
.filter( card -> card instanceof SuitCard ) // reject Jokers
.collect( Collectors.groupingBy( SuitCard::getSuit, Collectors.counting() ) );

请注意巧妙地插入了一个过滤器,以确保所考虑的卡片实际上是花色卡片而不是 clown 。但它不起作用!显然,collect 行没有意识到它所传递的对象一定是 SuitCard

在对此困惑了好一阵子之后,无奈之下我尝试插入一个 map 函数调用,令人惊讶的是它成功了!

Map<Suit, Long> countBySuit = contents.stream() // contents is ArrayList<Card>  
.filter( card -> card instanceof SuitCard ) // reject Jokers
.map( card -> (SuitCard)card ) // worked to get rid of error message on next line
.collect( Collectors.groupingBy( SuitCard::getSuit, Collectors.counting() ) );

我不知道转换类型被认为是可执行语句。为什么这行得通?为什么编译器需要它?

最佳答案

记住 filter操作不会更改 Stream 的编译时类型的元素。是的,从逻辑上讲,我们看到所有超过这一点的东西都将是 SuitCard。 , 所有 filter看到是一个Predicate .如果该谓词稍后更改,则可能会导致其他编译时问题。

如果你想把它改成Stream<SuitCard> ,您需要添加一个为您进行转换的映射器:

Map<Suit, Long> countBySuit = contents.stream() // Stream<Card>
.filter( card -> card instanceof SuitCard ) // still Stream<Card>, as filter does not change the type
.map( SuitCard.class::cast ) // now a Stream<SuitCard>
.collect( Collectors.groupingBy( SuitCard::getSuit, Collectors.counting() ) );

我建议您引用 Javadoc了解全部详情。

关于java - 在 Java 8 流中转换类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39840749/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com