2015-03-04 4 views
2

Я использую Java 8, и я хочу решить свою проблему, используя List.stream() functionnality.Вычислить сумму атрибута объекта в списке List (с потоком)

Вот моя проблема:

Это Score класса (Player класса не имеет значения):

public class Score { 

    private Player player; 
    private int score; 

    public Player getPlayer() { 
     return player; 
    } 

    public void setPlayer(Player player) { 
     this.player = player; 
    } 

    public int getScore() { 
     return score; 
    } 

    public void setScore(int score) { 
     this.score = score; 
    } 
} 

В начале моей программы, у меня есть список игроков, населенный:

List<Player> players; // Populated elsewhere 

Моя программа затем выполняет то, что она должна делать, и я получаю переменную этого типа:

List<List<Score>> scores; // Populated elsewhere 

Теперь я хочу, чтобы напечатать форматированный вывод, например, как это для каждого игрока:

Player.getName() + " : " + averagedScore; 

где averagedScore является суммой стоимости score.getScore() для одного Player делится на число вхождений в Score для этого Игрок в моих scores переменных.


Теперь, что я сделал до сих пор:

for (Players player : players) { 
    scores.stream().filter(x -> x.stream().anyMatch(y -> y.getPlayer().equals(player))); 
} 

Но я не вижу, как рассчитать сумму element.getScore(), содержащуюся в подсписков и фильтруется element.getPlayer()

ответ

4

Вы могли бы используйте комбинацию сборщиков groupingBy и averagingInt после того, как «flatMapped» ваш список списков:

Map<Player, Double> scoreByPlayer = scores.stream() 
       .flatMap(List::stream) 
       .collect(groupingBy(Score::getPlayer, averagingInt(Score::getScore))); 

scoreByPlayer.forEach((p, s) -> System.out.println(p + " : " + s)); 

Примечание: требуются следующие статические импорта:

import static java.util.stream.Collectors.averagingInt; 
import static java.util.stream.Collectors.groupingBy; 


Для справки, полный пример:

public static void main(String[] args) { 
    Player adam = new Player("Adam"); 
    Player pat = new Player("Pat"); 
    Player susie = new Player("Susie"); 
    List<List<Score>> scores = new ArrayList<>(); 
    scores.add(Arrays.asList(s(adam, 1), s(pat, 2), s(susie, 3))); 
    scores.add(Arrays.asList(s(adam, 2), s(pat, 4), s(susie, 6))); 
    scores.add(Arrays.asList(s(adam, 3), s(pat, 6), s(susie, 9))); 

    Map<Player, Double> scoreByPlayer = scores.stream() 
        .flatMap(List::stream) 
        .collect(groupingBy(Score::getPlayer, averagingInt(Score::getScore))); 

    scoreByPlayer.forEach((p, s) -> System.out.println(p + " : " + s)); 
} 

private static Score s(Player p, int score) { return new Score(p, score); } 

public static class Score { 
    private final Player player; 
    private final int score; 
    public Score(Player player, int score) { 
    this.player = player; 
    this.score = score; 
    } 

    public Player getPlayer() { return player; } 
    public int getScore() { return score; } 
} 

public static class Player { 
    private final String name; 
    public Player(String name) { this.name = name; } 
    @Override public String toString() { return name; } 
} 
+0

Awesome, спасибо большое! Работает так, как ожидалось. – Thrax

Смежные вопросы