在Java中获取列表列表中的最大值

huangapple go评论74阅读模式
英文:

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&lt;Card&gt; 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 -&gt; x.getTeam().equals(teamA))
	.map(n -&gt; n.getCards()
	.stream()
	.map( c -&gt; c.getWeigthCard()).max(Comparator.naturalOrder()));

players is a list of players (4 players)

error:

Type mismatch: cannot convert from Stream&lt;Object&gt; to int

help me please, it's for academic work

答案1

得分: 4

mapToInt替换你两次的map调用,首先。然后你就不需要Comparator.naturalOrder()

其次,你第一个map调用包含这个lambda表达式:

n -&gt; n.getCards().stream().map(c -&gt; c.getWeightCard())

这将一个单独的n,无论它是什么,转换成一个由weightcard返回的流(这不是你粘贴的代码)。map的目的是将一种东西转换为另一种东西,而不是一系列的东西。你可以使用flatmap来实现这一点,所以你可以首先flatmap到一系列的cards,然后通过weightcard函数将其映射到一个int,然后你可以求最大值。

将所有内容放在一起:

int maxPointsTeamA = players
            .stream()
            .filter(x -&gt; x.getTeam().equals(teamA))
            .flatMap(n -&gt; n.getCards().stream())
            .mapToInt(c -&gt; 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 -&gt; n.getCards().stream().map(c -&gt; 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 -&gt; x.getTeam().equals(teamA))
            .flatMap(n -&gt; n.getCards().stream())
            .mapToInt(c -&gt; 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 -&gt; x.getTeam().equals(teamA))
        .flatMap(player -&gt; player.getCards()
                .stream()
                .map(card -&gt; 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 -&gt; x.getTeam().equals(teamA))
	               .flatMap(n -&gt; n.getCards()
	               .stream().map(c -&gt; 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&lt;Player&gt; maxCardWeightPlayer = players
        .stream()
        .filter(x -&gt; x.getTeam().equals(teamA)) // filter players by team
        .max(Comparator.comparing(player -&gt; 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&lt;Player&gt; players = getTestData();
Player onePlayer = players.get(players.size()/2);//3rd player when list has 5 players.
List&lt;Card&gt; 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(&quot;Expected max: &quot; + onePlayerCards.get(onePlayerCards.size()-1).getWeightCard());
System.out.println(&quot;Actual max: &quot; + max);
}
public static int getMax(List&lt;Player&gt; players, Team team){
//Replace this with method with any other method you&#39;d like to test.
return getMax_byMasterJoe2(players, team);
}
public static int getMax_byMasterJoe2(List&lt;Player&gt; players, Team team){
Integer max = players
.stream()
//Extract player whose team is teamA.
.filter(player -&gt; player.getTeam().equals(team))
//Get the cards of a player.
//.map() gives us Stream&lt;List&lt;Card&gt;&gt;. flatMap() gives us Stream&lt;Card&gt; which is what we need.
.flatMap(player -&gt; player.getCards().stream())
//Get only the weights of each card of a player.
.mapToInt(Card::getWeightCard)
//Get maximum weight of a player&#39;s cards.
.max()
//If player has zero cards, then return 0.
.orElse(0);
return max;
}
public static List&lt;Player&gt; getTestData(){
List&lt;Player&gt; players = Stream
//Players numbers.
.of(1,2,3,4,5)
//Use player number to make player object.
.map(n -&gt; new Player(
//Player name.
&quot;player&quot; + 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 -&gt; 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;
}
}

huangapple
  • 本文由 发表于 2020年3月16日 08:06:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/60698922.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定