Максимальное значение из списка в Java - PullRequest
0 голосов
/ 16 марта 2020

Я пытаюсь получить максимальное значение, применяя фильтр

У меня есть объект, который содержит объект команды и список карт. поэтому мне нужно получить наибольшее значение из списка карт в атрибуте веса карты, где команда А, и вернуть игрока.

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
}

код, который я пытался выполнить

int maxPointsTeamA = players
    .stream()
    .filter( x -> x.getTeam().equals(teamA))
    .map(n -> n.getCards()
    .stream()
    .map( c -> c.getWeigthCard()).max(Comparator.naturalOrder()));

Players - это список игроков (4 игрока)

ошибка:

Type mismatch: cannot convert from Stream<Object> to int

помогите мне, пожалуйста, это для Academi c работа

Ответы [ 5 ]

3 голосов
/ 16 марта 2020

Замените оба ваших map звонка на mapToInt, для начинающих. Тогда вам не нужно Comparator.naturalOrder().

Во-вторых, ваш первый вызов карты содержит эту лямбду:

n -> n.getCards().stream().map(c -> c.getWeightCard()).

, которая превращает один 'n', что бы это ни было, в поток любой карты весов (которая не является вставленным вами кодом). Цель map - превратить одну вещь в одну другую вещь, а не в поток вещей. Вместо этого вы можете использовать flatmap для этого, предположительно, сначала flatMap с потоком карт, затем сопоставить его с 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; исправлена.

2 голосов
/ 16 марта 2020

Ответ основан на ожидании

, поэтому мне нужно получить максимальное значение из списка карт в атрибуте веса карты , где команда - A и возвращают игрока .

При поиске игрока, которого нужно вернуть, вы не должны отображать Stream, скорее найдите max с помощью пользовательского Comparator как

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
2 голосов
/ 16 марта 2020

Попробуйте это.

  • преобразовать список в поток.
  • фильтр для правильной команды
  • Затем создайте поток весов и выберите максимальное
            int maxCardWeightPlayerTeamA = players
                   .stream()
                   .filter( x -> x.getTeam().equals(teamA))
                   .flatMap(n -> n.getCards()
                   .stream().map(c -> c.getWeightCard()))
                    .max(Comparator.naturalOrder())
                   .orElse(-1);

Это было проверено с аналогичными классами и работает правильно.

2 голосов
/ 16 марта 2020

Это должно работать

int maxPointsTeamA= players
        .stream()
        .filter( x -> x.getTeam().equals(teamA))
        .flatMap(player -> player.getCards()
                .stream()
                .map(card -> card.getWeightCard()))
        .max(Comparator.naturalOrder())
        .orElse(0);
0 голосов
/ 17 марта 2020

Другие уже дали хорошие ответы. Но вот ответ, который также генерирует для вас тестовые данные (с использованием потоков) и позволяет получить максимальный

Переопределить / определить метод toString () для 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;
  }
}

Решение: Я добавил комментарии в код, чтобы объяснить, как работает решение.

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;
  }
}
...