Java:如何将对象从 List<T> 添加到 Map(键:枚举,值 List<T>)

我正在尝试将对象从添加List<Farm>到Map<Animal, List<Farm>>


public class Farm {

    private String farmName;

    private EnumSet<Animal> animals = EnumSet.noneOf(Animal.class);

    /* ... */

}


Farm f1 = new Farm("Farm A", EnumSet.of(Animal.CAT, Animal.DOG, Animal.DUCK));

Farm f2 = new Farm("Farm B", EnumSet.of(Animal.PIG, Animal.CAT, Animal.HORSE));

Farm f3 = new Farm("Farm C", EnumSet.of(Animal.DUCK));

任务 1:将对象添加到List<Farm>


List<Farm> list = new ArrayList<>();

list.add(f1);

list.add(f2);

list.add(f3);

任务 2:将列表中的对象添加到地图(键:Animal,值:)List <Farm>我以这种方式完成了这项任务:


Map<Animal, List<Farm>> map = new HashMap<>();


for(Farm farm: list) {

    for(Animal an: farm.getAnimals()) {

        if(!map.containsKey(an)) {

            List<Farm> new_list = new ArrayList<>();

            new_list.add(farm);

            map.put(an, new_list);

        }else {     

            List<Farm> old_list = map.get(an);

            if(!old_list.contains(farm)) {

                old_list.add(farm);

                    }

            }

        }

    }

有第二个/更有效的解决方案吗?是这样的:


Map<Animal, List<Farm>> map = list.stream().collect(Collectors.groupingBy(Farm::getAnimals)));

这不起作用,因为getAnimals返回一个EnumSet<Animal>.


呼唤远方
浏览 96回答 2
2回答

茅侃侃

您可能希望保留循环,但对其进行现代化改造:Map<Animal, List<Farm>> map = new EnumMap<>(Animal.class);for(Farm farm: list)&nbsp; &nbsp; for(Animal an: farm.getAnimals())&nbsp; &nbsp; &nbsp; &nbsp; map.computeIfAbsent(an, x -> new ArrayList<>()).add(farm);在你的循环中,add(farm)冗余出现在两个分支中,因为你总是将它添加到List. 然后,computeIfAbsent允许消除条件,因为它将返回一个现有值或构造一个新值,放入并返回它。收集groupingBy器在内部也使用这种方法。使用 Stream 操作的缺点是您需要临时持有两个值,例如Map<Animal, List<Farm>> map = list.stream()&nbsp; &nbsp; .flatMap(farm -> farm.getAnimals().stream()&nbsp; &nbsp; &nbsp; &nbsp; .map(animal -> new AbstractMap.SimpleImmutableEntry<>(animal, farm)))&nbsp; &nbsp; .collect(Collectors.groupingBy(Map.Entry::getKey,&nbsp; &nbsp; &nbsp; &nbsp; () -> new EnumMap<>(Animal.class),&nbsp; &nbsp; &nbsp; &nbsp; Collectors.mapping(Map.Entry::getValue, Collectors.toList())));

温温酱

我从对面开始,但我想这很有帮助&nbsp;&nbsp;&nbsp;&nbsp;Map<Animal,&nbsp;List<Farm>>&nbsp;map&nbsp;=&nbsp;Arrays.stream(Animal.values()) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.collect(Collectors.toMap(an&nbsp;->&nbsp;an,&nbsp;an&nbsp;->&nbsp;list.stream().filter(f&nbsp;->&nbsp;f.getAnimals().contains(an)).collect(Collectors.toList())));在没有任何农场包含动物的情况下,动物可能有空集,但这可以很容易地过滤
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java