首页 文章

Java 8将<V>列入Map <K,V>

提问于
浏览
751

我想使用Java 8的流和lambdas将对象列表转换为Map .

这就是我在Java 7及以下版本中编写它的方法 .

private Map<String, Choice> nameMap(List<Choice> choices) {
        final Map<String, Choice> hashMap = new HashMap<>();
        for (final Choice choice : choices) {
            hashMap.put(choice.getName(), choice);
        }
        return hashMap;
}

我可以使用Java 8和Guava轻松完成此任务,但我想知道如何在没有Guava的情况下完成此操作 .

在 Guava :

private Map<String, Choice> nameMap(List<Choice> choices) {
    return Maps.uniqueIndex(choices, new Function<Choice, String>() {

        @Override
        public String apply(final Choice input) {
            return input.getName();
        }
    });
}

和 Guava 与Java 8 lambdas .

private Map<String, Choice> nameMap(List<Choice> choices) {
    return Maps.uniqueIndex(choices, Choice::getName);
}

17 回答

  • 3

    我用这个语法

    Map<Integer, List<Choice>> choiceMap = 
    choices.stream().collect(Collectors.groupingBy(choice -> choice.getName()));
    
  • 123
    Map<String, Set<String>> collect = Arrays.asList(Locale.getAvailableLocales()).stream().collect(Collectors
                    .toMap(l -> l.getDisplayCountry(), l -> Collections.singleton(l.getDisplayLanguage())));
    
  • 9

    我试图这样做,并发现,使用上面的答案,当使用 Functions.identity() 作为Map的键时,我遇到了使用像 this::localMethodName 这样的本地方法因为输入问题而实际工作的问题 .

    Functions.identity() 实际上对这种情况下的输入做了一些事情,所以该方法只能通过返回 Object 并接受 Object 的参数来工作

    为了解决这个问题,我最终放弃 Functions.identity() 并改为使用 s->s .

    所以我的代码,在我的情况下列出目录中的所有目录,并为每个目录使用目录的名称作为 Map 的键,然后调用具有目录名称的方法并返回项目的集合,如下所示:

    Map<String, Collection<ItemType>> items = Arrays.stream(itemFilesDir.listFiles(File::isDirectory))
    .map(File::getName)
    .collect(Collectors.toMap(s->s, this::retrieveBrandItems));
    
  • 8

    可以使用流来执行此操作 . 为了消除显式使用 Collectors 的需要,可以静态导入 toMap (按照Effective Java,第三版的建议) .

    import static java.util.stream.Collectors.toMap;
    
    private static Map<String, Choice> nameMap(List<Choice> choices) {
        return choices.stream().collect(toMap(Choice::getName, it -> it));
    }
    
  • 1128

    这可以通过两种方式完成 . 让人成为我们将要用来演示它的课程 .

    public class Person {
    
        private String name;
        private int age;
    
        public String getAge() {
            return age;
        }
    }
    

    persons 是要转换为 Map 的人员列表

    1.在列表中使用简单的foreach和Lambda表达式

    Map<Integer,List<Person>> mapPersons = new HashMap<>();
    persons.forEach(p->mapPersons.put(p.getAge(),p));
    

    2.在给定列表上定义的Stream上使用收集器 .

    Map<Integer,List<Person>> mapPersons = 
               persons.stream().collect(Collectors.groupingBy(Person::getAge));
    
  • 0

    例如,如果要将对象字段转换为映射:

    示例对象:

    class Item{
            private String code;
            private String name;
    
            public Item(String code, String name) {
                this.code = code;
                this.name = name;
            }
    
            //getters and setters
        }
    

    并且操作转换List To Map:

    List<Item> list = new ArrayList<>();
    list.add(new Item("code1", "name1"));
    list.add(new Item("code2", "name2"));
    
    Map<String,String> map = list.stream()
         .collect(Collectors.toMap(Item::getCode, Item::getName));
    
  • 4

    我将编写如何使用 genericsinversion of control 将列表转换为映射 . 只是 universal method!

    Maybe 我们有 list of Integersobjects. 列表所以问题如下:应该是什么 key of the map?

    创建界面

    public interface KeyFinder<K, E> {
        K getKey(E e);
    }
    

    现在使用控制反转:

    static <K, E> Map<K, E> listToMap(List<E> list, KeyFinder<K, E> finder) {
            return  list.stream().collect(Collectors.toMap(e -> finder.getKey(e) , e -> e));
        }
    

    例如,如果我们有书的对象,这个类就是为 Map 选择键

    public class BookKeyFinder implements KeyFinder<Long, Book> {
        @Override
        public Long getKey(Book e) {
            return e.getPrice()
        }
    }
    
  • 16

    列出的大部分答案都错过了 list has duplicate items 的情况 . 在那种情况下,答案会抛出 IllegalStateException . 请参阅以下代码 to handle list duplicates

    public Map<String, Choice> convertListToMap(List<Choice> choices) {
        return choices.stream()
            .collect(Collectors.toMap(Choice::getName, choice -> choice,
                (oldValue, newValue) -> newValue));
      }
    
  • 3

    这是StreamEx的解决方案

    StreamEx.of(choices).toMap(Choice::getName, c -> c);
    
  • 232

    如果您不想使用Collectors.toMap(),这是另一个

    Map<String, Choice> result =
       choices.stream().collect(HashMap<String, Choice>::new, 
                               (m, c) -> m.put(c.getName(), c),
                               (m, u) -> {});
    
  • 0

    使用getName()作为键和选择本身作为映射的值:

    Map<String, Choice> result =
        choices.stream().collect(Collectors.toMap(Choice::getName, c -> c));
    
  • 9

    基于Collectors documentation,它很简单:

    Map<String, Choice> result =
        choices.stream().collect(Collectors.toMap(Choice::getName,
                                                  Function.identity()));
    
  • 7

    如果您的密钥 NOT 保证对列表中的所有元素都是唯一的,则应将其转换为 Map<String, List<Choice>> 而不是 Map<String, Choice>

    Map<String, List<Choice>> result =
     choices.stream().collect(Collectors.groupingBy(Choice::getName));
    
  • 0

    如果您没有't mind using 3rd party libraries, AOL' lib(披露我是贡献者),所有JDK Collection类型都有扩展名,包括ListMap .

    ListX<Choices> choices;
    Map<String, Choice> map = choices.toMap(c-> c.getName(),c->c);
    
  • 2

    您可以使用IntStream创建索引流,然后将它们转换为Map:

    Map<Integer,Item> map = 
    IntStream.range(0,items.size())
             .boxed()
             .collect(Collectors.toMap (i -> i, i -> items.get(i)));
    
  • 5

    以简单的方式再添一个选项

    Map<String,Choice> map = new HashMap<>();
    choices.forEach(e->map.put(e.getName(),e));
    
  • 11
    Map<String,Choice> map=list.stream().collect(Collectors.toMap(Choice::getName, s->s));
    

    甚至为我这个目的,

    Map<String,Choice> map=  list1.stream().collect(()-> new HashMap<String,Choice>(), 
                (r,s) -> r.put(s.getString(),s),(r,s) -> r.putAll(s));
    

相关问题