Посмотрите на код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
import java.util.Arrays; import java.util.Map; import java.util.stream.Collectors; public class MonsterMapMain { public static void main(String[] args) { class Monster { private String id; private String name; private double health; public Monster(String id, String name, double health) { super(); this.id = id; this.name = name; this.health = health; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getHealth() { return health; } public void setHealth(double health) { this.health = health; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("Monster [id="); builder.append(id); builder.append(", name="); builder.append(name); builder.append(", health="); builder.append(health); builder.append("]"); return builder.toString(); } } Monster[] monsterArray = new Monster[] { new Monster("id1", "ambush_monster", 100.0), new Monster("id2", "green_monster", 200.0), new Monster("id1", "rare monster", 33.0), new Monster("id3", "boss", 55.0) }; Map<String, Monster> map = Arrays.stream(monsterArray) .collect(Collectors.toMap(Monster::getId, monster -> monster)); } } |
Здесь мы в monsterArray храним два монстра с одинаковым "id1", что приведёт к ошибке при запуске программы:
1 2 3 4 5 6 7 8 9 10 11 12 |
Exception in thread "main" java.lang.IllegalStateException: Duplicate key Monster [id=id1, name=ambush_monster, health=100.0] at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133) at java.util.HashMap.merge(HashMap.java:1254) at java.util.stream.Collectors.lambda$toMap$58(Collectors.java:1320) at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169) at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) at MonsterMapMain.main(MonsterMapMain.java:66) |
Чтобы избавиться от этого исключения мы можем использовать метод Collectors.toMap с тремя параметрами, где третьим параметром мы передаём лямбду, возвращающую того монстра из двух, которого нужно оставить при дубликатах:
1 2 3 4 5 6 |
Map<String, Monster> map = Arrays.stream(monsterArray) .collect(Collectors.toMap( Monster::getId, monster -> monster, (monster1, monster2) -> monster1.getHealth() > monster2.getHealth() ? monster1 : monster2)); |
Вот и всё.