将 HashMap<Integer, Long> 转换为 HashMap<Integer, Integer>
Convert a HashMap<Integer, Long> ito HashMap<Integer, Integer>
Collectors.counting()
returns long
此方法中每个键的值:
private static Map<Integer, Long> countDuplicates(HashSet<Card> cards) {
return cards.stream().collect(Collectors.groupingBy(Card::getRankNumber, Collectors.counting()));
}
有没有办法将结果 Map
从 Map<Integer, Long>
转换或转换为 Map<Integer, Integer>
?
直接转换给出了这个异常:
Type mismatch: cannot convert from Map<Integer,Integer> to Map<Integer,Long>
注:我的class的实现保证了cards
里面有5个对象,所以没有机会溢出。
尝试以下操作:
private static Map<Integer, Integer> countDuplicates(HashSet<Card> cards) {
return cards.stream()
.collect(Collectors.groupingBy(Card::getRankNumber, Collectors.summingInt(x -> 1)));
}
而不是 Collectors.counting()
使用 Collectors.summingInt(x -> 1)
以便您立即获得整数值。
获得Map<Integer, Integer>
的另一种方法是使用toMap
收集器和Integer::sum
method reference作为合并函数:
private static Map<Integer, Integer> countDuplicates(HashSet<Card> cards) {
return cards.stream()
.collect(Collectors.toMap(Card::getRankNumber, x -> 1, Integer::sum));
}
两个 and the 似乎都是正确的。这是我为尝试这两种方法而编写的示例代码。
Card
class.
package work.basil.example;
import java.util.Objects;
public class Card
{
public enum Suit
{
CLUB, DIAMOND, HEART, SPADE
}
// -------------| Member fields |-----------------------
private Suit suit;
private String name;
private Integer rankNumber;
// -------------| Constructors |-----------------------
public Card ( Suit suit , String name , Integer rankNumber )
{
Objects.requireNonNull( suit );
Objects.requireNonNull( name );
Objects.requireNonNull( rankNumber );
this.suit = suit;
this.name = name;
this.rankNumber = rankNumber;
}
// -------------| Getters |-----------------------
public String getName ( ) { return this.name; }
public Integer getRankNumber ( ) { return this.rankNumber; }
// -------------| Object methods |-----------------------
@Override
public String toString ( )
{
return "Card{ " +
"suit=" + suit +
" | name='" + name + '\'' +
" | rankNumber=" + rankNumber +
" }";
}
@Override
public boolean equals ( Object o )
{
if ( this == o ) return true;
if ( o == null || getClass() != o.getClass() ) return false;
Card card = ( Card ) o;
return suit == card.suit && getName().equals( card.getName() ) && getRankNumber().equals( card.getRankNumber() );
}
@Override
public int hashCode ( )
{
return Objects.hash( suit , getName() , getRankNumber() );
}
}
在 Java 16 及更高版本中,我们可以将 Card
class 简化为简短的 record
。在更下方的代码中,我们将 getRankNumber
更改为隐式 getter 方法 rankNumber
。 Suit
枚举将移动到它自己的 .java 文件。
package work.basil.example.cardgame;
public record Card( Suit suit , String name , Integer rankNumber )
{
}
CastingStream
class 收集那些卡片。
package work.basil.example;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
public class CastingStream
{
public static void main ( String[] args )
{
CastingStream app = new CastingStream();
app.demo();
}
private void demo ( )
{
Set < Card > cards = Set.of(
new Card( Card.Suit.HEART , "Ten" , 10 ) ,
new Card( Card.Suit.SPADE , "Ten" , 10 ) ,
new Card( Card.Suit.HEART , "Queen" , 12 )
);
// Code taken from Question.
Map < Integer, Long > countDuplicatesLong =
cards
.stream()
.collect(
Collectors.groupingBy(
Card :: getRankNumber ,
Collectors.counting()
)
);
// Code taken from Answer by dreamcrash.
Map < Integer, Integer > countDuplicatesIntegerBySummingInt =
cards
.stream()
.collect(
Collectors.groupingBy(
Card :: getRankNumber ,
Collectors.summingInt( x -> 1 )
)
);
// Code taken from Answer by Alex Rudenko.
Map < Integer, Integer > countDuplicatesIntegerBySumMethodReference =
cards
.stream()
.collect(
Collectors.toMap( Card :: getRankNumber ,
x -> 1 ,
Integer :: sum
)
);
System.out.println( "cards = " + cards );
System.out.println( "countDuplicatesLong = " + countDuplicatesLong );
System.out.println( "countDuplicatesIntegerBySummingInt = " + countDuplicatesIntegerBySummingInt );
System.out.println( "countDuplicatesIntegerBySumMethodReference = " + countDuplicatesIntegerBySumMethodReference );
}
}
当运行.
cards = [Card{ suit=HEART | name='Queen' | rankNumber=12 }, Card{ suit=HEART | name='Ten' | rankNumber=10 }, Card{ suit=SPADE | name='Ten' | rankNumber=10 }]
countDuplicatesLong = {10=2, 12=1}
countDuplicatesIntegerBySummingInt = {10=2, 12=1}
countDuplicatesIntegerBySumMethodReference = {10=2, 12=1}
Collectors.counting()
returns long
此方法中每个键的值:
private static Map<Integer, Long> countDuplicates(HashSet<Card> cards) {
return cards.stream().collect(Collectors.groupingBy(Card::getRankNumber, Collectors.counting()));
}
有没有办法将结果 Map
从 Map<Integer, Long>
转换或转换为 Map<Integer, Integer>
?
直接转换给出了这个异常:
Type mismatch: cannot convert from Map<Integer,Integer> to Map<Integer,Long>
注:我的class的实现保证了cards
里面有5个对象,所以没有机会溢出。
尝试以下操作:
private static Map<Integer, Integer> countDuplicates(HashSet<Card> cards) {
return cards.stream()
.collect(Collectors.groupingBy(Card::getRankNumber, Collectors.summingInt(x -> 1)));
}
而不是 Collectors.counting()
使用 Collectors.summingInt(x -> 1)
以便您立即获得整数值。
获得Map<Integer, Integer>
的另一种方法是使用toMap
收集器和Integer::sum
method reference作为合并函数:
private static Map<Integer, Integer> countDuplicates(HashSet<Card> cards) {
return cards.stream()
.collect(Collectors.toMap(Card::getRankNumber, x -> 1, Integer::sum));
}
两个
Card
class.
package work.basil.example;
import java.util.Objects;
public class Card
{
public enum Suit
{
CLUB, DIAMOND, HEART, SPADE
}
// -------------| Member fields |-----------------------
private Suit suit;
private String name;
private Integer rankNumber;
// -------------| Constructors |-----------------------
public Card ( Suit suit , String name , Integer rankNumber )
{
Objects.requireNonNull( suit );
Objects.requireNonNull( name );
Objects.requireNonNull( rankNumber );
this.suit = suit;
this.name = name;
this.rankNumber = rankNumber;
}
// -------------| Getters |-----------------------
public String getName ( ) { return this.name; }
public Integer getRankNumber ( ) { return this.rankNumber; }
// -------------| Object methods |-----------------------
@Override
public String toString ( )
{
return "Card{ " +
"suit=" + suit +
" | name='" + name + '\'' +
" | rankNumber=" + rankNumber +
" }";
}
@Override
public boolean equals ( Object o )
{
if ( this == o ) return true;
if ( o == null || getClass() != o.getClass() ) return false;
Card card = ( Card ) o;
return suit == card.suit && getName().equals( card.getName() ) && getRankNumber().equals( card.getRankNumber() );
}
@Override
public int hashCode ( )
{
return Objects.hash( suit , getName() , getRankNumber() );
}
}
在 Java 16 及更高版本中,我们可以将 Card
class 简化为简短的 record
。在更下方的代码中,我们将 getRankNumber
更改为隐式 getter 方法 rankNumber
。 Suit
枚举将移动到它自己的 .java 文件。
package work.basil.example.cardgame;
public record Card( Suit suit , String name , Integer rankNumber )
{
}
CastingStream
class 收集那些卡片。
package work.basil.example;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
public class CastingStream
{
public static void main ( String[] args )
{
CastingStream app = new CastingStream();
app.demo();
}
private void demo ( )
{
Set < Card > cards = Set.of(
new Card( Card.Suit.HEART , "Ten" , 10 ) ,
new Card( Card.Suit.SPADE , "Ten" , 10 ) ,
new Card( Card.Suit.HEART , "Queen" , 12 )
);
// Code taken from Question.
Map < Integer, Long > countDuplicatesLong =
cards
.stream()
.collect(
Collectors.groupingBy(
Card :: getRankNumber ,
Collectors.counting()
)
);
// Code taken from Answer by dreamcrash.
Map < Integer, Integer > countDuplicatesIntegerBySummingInt =
cards
.stream()
.collect(
Collectors.groupingBy(
Card :: getRankNumber ,
Collectors.summingInt( x -> 1 )
)
);
// Code taken from Answer by Alex Rudenko.
Map < Integer, Integer > countDuplicatesIntegerBySumMethodReference =
cards
.stream()
.collect(
Collectors.toMap( Card :: getRankNumber ,
x -> 1 ,
Integer :: sum
)
);
System.out.println( "cards = " + cards );
System.out.println( "countDuplicatesLong = " + countDuplicatesLong );
System.out.println( "countDuplicatesIntegerBySummingInt = " + countDuplicatesIntegerBySummingInt );
System.out.println( "countDuplicatesIntegerBySumMethodReference = " + countDuplicatesIntegerBySumMethodReference );
}
}
当运行.
cards = [Card{ suit=HEART | name='Queen' | rankNumber=12 }, Card{ suit=HEART | name='Ten' | rankNumber=10 }, Card{ suit=SPADE | name='Ten' | rankNumber=10 }]
countDuplicatesLong = {10=2, 12=1}
countDuplicatesIntegerBySummingInt = {10=2, 12=1}
countDuplicatesIntegerBySumMethodReference = {10=2, 12=1}