writeRead.getArrayList(this).stream()
.map(Game::getWinnerGamer)
.collect(Collectors.groupingBy(Gamer::getName, Collectors.summingInt(Gamer::getLeaderboardScore)))
.entrySet()
.stream()
.sorted(Comparator.comparing(Map.Entry<String, Integer>::getValue).reversed())
.map(entry -> new Gamer(entry.getKey(), entry.getValue()))
.collect(Collectors.toList());
Шаги:
Мой ответ основан на предположении, что у вас есть такая структура:
class Game {
private Gamer winnerGamer;
// getter & setter
}
class Gamer {
private String name;
private Integer leaderboardScore;
// getters & setters && AllArgsContructor
}
Кстати: если вы переопределяете равенства и хеш-код в классе Gamer, вы можете избежать воссоздания Gamer с помощью этого:
writeRead.getArrayList(this).stream()
.map(Game::getWinnerGamer)
.collect(Collectors.groupingBy(Function.identity(), Collectors.summingInt(Gamer::getLeaderboardScore)))
.entrySet()
.stream()
.sorted(Comparator.comparing(Map.Entry<Gamer, Integer>::getValue).reversed())
.map(Map.Entry::getKey)
.collect(Collectors.toList());
dynamic
может упростить ограниченное количество сценариев отражения (где вы знаете имя члена заранее, но нет интерфейса) - в частности, это может помочь с универсальными операторами (, хотя существуют другие ответы ), но, кроме уловки с обобщенными операторами, существует небольшое пересечение с универсальными шаблонами.
Универсальные шаблоны позволяют вам знать (во время компиляции) о типе, с которым вы работаете - и наоборот, динамический
не заботится о типе.
В частности, универсальные шаблоны позволяют вам указать и подтвердить ряд условий относительно типа, т.е. он может реализовывать некоторый интерфейс или иметь общедоступный конструктор без параметров. dynamic
тоже не помогает: он не поддерживает интерфейсы, и, что хуже, чем просто не заботиться об интерфейсах, это означает, что мы не можем даже увидеть явные реализации интерфейса с динамический
.
Кроме того, динамический
на самом деле является частным случаем объекта
, поэтому бокс вступает в игру, но с удвоенной силой.
В действительности, вам следует ограничить использование динамического
несколькими случаями:
Для всех остальных случаев лучше всего подходят универсальные шаблоны и обычный C #.
Чтобы ответить на ваш вопрос. Нет.
List
и затем могу использовать его для списка строк, целых чисел и т. Д. Ключевое слово dynamic
даст вам
Динамические классы и универсальные шаблоны это совершенно разные понятия. С помощью дженериков вы определяете типы во время компиляции. Они не меняются, они не динамичны. Вы просто помещаете «заполнитель» в некоторый класс или метод, чтобы вызывающий код определял тип.
Динамические методы определяются во время выполнения. У вас нет безопасности типов во время компиляции. Динамический класс аналогичен тому, как если бы у вас были ссылки на объекты и методы вызова по его строковым именам с использованием отражения.
Чтобы ответить на ваш первый вопрос, обобщенные типы - это разрешенные во время компиляции, динамические типы во время выполнения. Таким образом, существует определенная разница в безопасности типов и скорости.
Ответ на второй вопрос: вы можете возвращать анонимные типы в C # 3.0. Приведите тип к объекту, верните его и используйте отражение для доступа к его членам. Ключевое слово dynamic - всего лишь синтаксический сахар для этого.