英文:
Max value from list of list in Java
问题
我试图通过应用过滤器来获取最高值。
我有一个包含团队对象和卡片列表的对象。
因此,我需要从卡片列表中获取卡片权重属性的最高值,在团队为A的情况下,返回球员。
以下是我尝试执行的代码:
int maxPointsTeamA = players
.stream()
.filter(x -> x.getTeam().equals(teamA))
.map(n -> n.getCards()
.stream()
.map(c -> c.getWeightCard())
.max(Comparator.naturalOrder())
.orElse(0)) // 添加orElse来处理可能的空值情况
.max(Comparator.naturalOrder())
.orElse(0); // 添加orElse来处理可能的空值情况
players
是一个包含4名球员的列表。
错误:
Type mismatch: cannot convert from Stream<Object> to int
请帮我,这是为了学术工作。
英文:
I'm trying to get the highest value by applying a filter
I have an object that contains a team object and a list of cards.
so I need to get the highest value from the card list in the card weight attribute, where the team is A, and return the player.
public class Player {
private String name;
private List<Card> cards;
private Team team;
// getters and setters
}
public class Team {
private int id;
private int points;
// getters and setters
}
public class Card {
private int weightCard;
// getters and setters
}
the code that I was trying to execute
int maxPointsTeamA = players
.stream()
.filter( x -> x.getTeam().equals(teamA))
.map(n -> n.getCards()
.stream()
.map( c -> c.getWeigthCard()).max(Comparator.naturalOrder()));
players is a list of players (4 players)
error:
Type mismatch: cannot convert from Stream<Object> to int
help me please, it's for academic work
答案1
得分: 4
用mapToInt
替换你两次的map
调用,首先。然后你就不需要Comparator.naturalOrder()
。
其次,你第一个map调用包含这个lambda表达式:
n -> n.getCards().stream().map(c -> c.getWeightCard())
。
这将一个单独的n
,无论它是什么,转换成一个由weightcard返回的流(这不是你粘贴的代码)。map
的目的是将一种东西转换为另一种东西,而不是一系列的东西。你可以使用flatmap
来实现这一点,所以你可以首先flatmap到一系列的cards,然后通过weightcard函数将其映射到一个int,然后你可以求最大值。
将所有内容放在一起:
int maxPointsTeamA = players
.stream()
.filter(x -> x.getTeam().equals(teamA))
.flatMap(n -> n.getCards().stream())
.mapToInt(c -> c.getWeightCard())
.max()
.orElse(0);
编辑:哦,是的,我忘记了max()会返回一个OptionalInt;已修正。
英文:
Replace both of your map
calls to mapToInt
, for starters. You then do not need the Comparator.naturalOrder()
.
Secondly, your first map call contains this lambda:
n -> n.getCards().stream().map(c -> c.getWeightCard())
.
That turns a single 'n', whatever that might be, into a stream of whatever weightcard returns (which is not code you pasted). The point of map
is to turn one thing into one other thing, not a stream of things. You can use flatmap
for that instead, so presumably, first flatMap to a stream of cards, then map that to an int via the weightcard function, and then you can max.
Putting it all together:
int maxPointsTeamA = players
.stream()
.filter(x -> x.getTeam().equals(teamA))
.flatMap(n -> n.getCards().stream())
.mapToInt(c -> c.getWeightCard())
.max()
.orElse(0);
EDIT: Ah, yes, I forgot max() returns an OptionalInt; fixed.
答案2
得分: 2
这应该可以工作
int maxPointsTeamA = players
.stream()
.filter(x -> x.getTeam().equals(teamA))
.flatMap(player -> player.getCards()
.stream()
.map(card -> card.getWeightCard()))
.max(Comparator.naturalOrder())
.orElse(0);
英文:
This should work
int maxPointsTeamA= players
.stream()
.filter( x -> x.getTeam().equals(teamA))
.flatMap(player -> player.getCards()
.stream()
.map(card -> card.getWeightCard()))
.max(Comparator.naturalOrder())
.orElse(0);
答案3
得分: 2
尝试一下这个。
- 将列表转换为流。
- 为正确的团队进行筛选。
- 然后创建一个权重流并选择最大值。
int maxCardWeightPlayerTeamA = players
.stream()
.filter(x -> x.getTeam().equals(teamA))
.flatMap(n -> n.getCards()
.stream().map(c -> c.getWeightCard()))
.max(Comparator.naturalOrder())
.orElse(-1);
这已经在类似的类上进行了测试,并且可以正常运行。
英文:
Try this.
- convert the list to a stream.
- filter for the correct team
- Then create a stream of the weights and select the max
int maxCardWeightPlayerTeamA = players
.stream()
.filter( x -> x.getTeam().equals(teamA))
.flatMap(n -> n.getCards()
.stream().map(c -> c.getWeightCard()))
.max(Comparator.naturalOrder())
.orElse(-1);
This has been tested with similar classes and operates correctly.
答案4
得分: 2
基于预期进行回答
所以我需要从卡牌列表中获取卡牌重量属性的最高值,其中队伍为A,然后返回玩家。
在寻找要返回的玩家时,您不应该映射Stream
,而是使用自定义的Comparator
来找到max
,如下所示:
Optional<Player> maxCardWeightPlayer = players
.stream()
.filter(x -> x.getTeam().equals(teamA)) // 按队伍筛选玩家
.max(Comparator.comparing(player -> player.getCards().stream()
.map(Card::getWeightCard)
.max(Comparator.naturalOrder()) // 最大的卡牌重量
.orElse(0))); // 根据最大卡牌重量找到最大的玩家
英文:
Answering based on the expectation
> so I need to get the highest value from the card list in the card
> weight attribute, where the team is A, and return the player.
While looking for a player to be returned, you should not map the Stream
, rather find the max
using the custom Comparator
as
Optional<Player> maxCardWeightPlayer = players
.stream()
.filter(x -> x.getTeam().equals(teamA)) // filter players by team
.max(Comparator.comparing(player -> player.getCards().stream()
.map(Card::getWeightCard)
.max(Comparator.naturalOrder()) // maximum card weight
.orElse(0))); // find max player by maximum card weight
答案5
得分: 0
其他人已经给出了很好的答案。但是,这里有一个同时为您生成测试数据(使用流)并让您获取最大值的答案。
重写/定义 Team 的 toString() 方法:
class Team {
private int id;
private int points;
@Override
public boolean equals(Object otherTeam){
Team t = (Team) otherTeam;
return this.getId() == t.getId() ? true : false;
}
}
解决方案:
我在代码中添加了注释来解释解决方案的工作原理。
class Test{
//主方法 - 从这里开始 !!!
public static void main(String [] args){
//准备测试数据。
List<Player> players = getTestData();
Player onePlayer = players.get(players.size()/2);//列表中有 5 名玩家时的第三名玩家。
List<Card> onePlayerCards = onePlayer.getCards();
Team teamA = new Team(onePlayer.getTeam().getId(), onePlayer.getTeam().getPoints());
//测试最大值查找器。
Integer max = getMax(players, teamA);
System.out.println("期望的最大值: " + onePlayerCards.get(onePlayerCards.size()-1).getWeightCard());
System.out.println("实际的最大值: " + max);
}
public static int getMax(List<Player> players, Team team){
//将此替换为您想要测试的任何其他方法。
return getMax_byMasterJoe2(players, team);
}
public static int getMax_byMasterJoe2(List<Player> players, Team team){
Integer max = players
.stream()
//提取所属团队为 teamA 的玩家。
.filter(player -> player.getTeam().equals(team))
//获取玩家的卡片。
//.map() 给我们提供 Stream<List<Card>>。flatMap() 给我们 Stream<Card>,这是我们所需的。
.flatMap(player -> player.getCards().stream())
//仅获取每张玩家卡片的权重。
.mapToInt(Card::getWeightCard)
//获取玩家卡片的最大权重。
.max()
//如果玩家没有卡片,则返回 0。
.orElse(0);
return max;
}
public static List<Player> getTestData(){
List<Player> players = Stream
//玩家编号。
.of(1,2,3,4,5)
//使用玩家编号创建玩家对象。
.map(n -> new Player(
//玩家名称。
"player" + n,
//为第 n 个玩家生成 n 张卡片。例如,n=3 给出权重为 10、20、30 的卡片。
IntStream.range(1, n+1).mapToObj(num -> new Card(num * 10)).collect(Collectors.toList()),
//团队。
new Team(n, n * 10)))
.collect(Collectors.toList());
//移除最后一个玩家的所有卡片以进行测试。
players.get(players.size()-1).getCards().clear();
return players;
}
}
英文:
Others have already given good answers. But, here is an answer which also generates test data for you (by using streams) and lets you get the max.
Override/define the toString() method for Team:
class Team {
private int id;
private int points;
@Override
public boolean equals(Object otherTeam){
Team t = (Team) otherTeam;
return this.getId() == t.getId() ? true : false;
}
}
Solution :
I have added comments in the code to explain how the solution works.
class Test{
//MAIN METHOD - START HERE !!!
public static void main(String [] args){
//Prepare test data.
List<Player> players = getTestData();
Player onePlayer = players.get(players.size()/2);//3rd player when list has 5 players.
List<Card> onePlayerCards = onePlayer.getCards();
Team teamA = new Team(onePlayer.getTeam().getId(), onePlayer.getTeam().getPoints());
//Test the max finder.
Integer max = getMax(players, teamA);
System.out.println("Expected max: " + onePlayerCards.get(onePlayerCards.size()-1).getWeightCard());
System.out.println("Actual max: " + max);
}
public static int getMax(List<Player> players, Team team){
//Replace this with method with any other method you'd like to test.
return getMax_byMasterJoe2(players, team);
}
public static int getMax_byMasterJoe2(List<Player> players, Team team){
Integer max = players
.stream()
//Extract player whose team is teamA.
.filter(player -> player.getTeam().equals(team))
//Get the cards of a player.
//.map() gives us Stream<List<Card>>. flatMap() gives us Stream<Card> which is what we need.
.flatMap(player -> player.getCards().stream())
//Get only the weights of each card of a player.
.mapToInt(Card::getWeightCard)
//Get maximum weight of a player's cards.
.max()
//If player has zero cards, then return 0.
.orElse(0);
return max;
}
public static List<Player> getTestData(){
List<Player> players = Stream
//Players numbers.
.of(1,2,3,4,5)
//Use player number to make player object.
.map(n -> new Player(
//Player name.
"player" + n,
//Generate n cards for n-th player. Ex. n=3 gives cards with weights 10, 20, 30.
IntStream.range(1, n+1).mapToObj(num -> new Card(num * 10)).collect(Collectors.toList()),
//Team.
new Team(n, n * 10)))
.collect(Collectors.toList());
//Remove all cards of last player for testing.
players.get(players.size()-1).getCards().clear();
return players;
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论