Java:如何将List <?>转换为Map <String,?>

ebt*_*ebt 8 java generics list map

我想找到一种方法来获取下面的对象特定例程并将其抽象为一个方法,您可以传递一个类,列表和字段名来获取一个Map.如果我可以在所使用的模式上获得一般指针,或者等等,这可以让我开始朝着正确的方向前进.

  Map<String,Role> mapped_roles = new HashMap<String,Role>();
    List<Role> p_roles = (List<Role>) c.list();
    for (Role el :  p_roles) {
        mapped_roles.put(el.getName(), el);
    }
Run Code Online (Sandbox Code Playgroud)

这个?(伪代码)

  Map<String,?> MapMe(Class clz, Collection list, String methodName)
  Map<String,?> map = new HashMap<String,?>();
    for (clz el :  list) {
        map.put(el.methodName(), el);
    }
Run Code Online (Sandbox Code Playgroud)

可能吗?

Jor*_*orn 33

使用Guava(以前的Google Collections):

Map<String,Role> mappedRoles = Maps.uniqueIndex(yourList, Functions.toStringFunction());
Run Code Online (Sandbox Code Playgroud)

或者,如果您想提供自己的方法,使其成为一个String对象:

Map<String,Role> mappedRoles = Maps.uniqueIndex(yourList, new Function<Role,String>() {
  public String apply(Role from) {
    return from.getName(); // or something else
  }});
Run Code Online (Sandbox Code Playgroud)

  • 我建议链接到Guava而不是Google Collections,因为Guava已经正式取代它. (3认同)
  • @Tom我觉得Google Collections/Guava是一个大多数Java项目都可以从中受益的库.特别是如果替代方案是从头开始重新实现其功能,并以更有限的方式(如你的答案)或做某事......不安全......就像反思答案一样. (3认同)

qua*_*oup 4

这就是我要做的。我不完全确定我是否正确处理泛型,但是哦,好吧:

public <T> Map<String, T> mapMe(Collection<T> list) {
   Map<String, T> map = new HashMap<String, T>();
   for (T el : list) {
       map.put(el.toString(), el);
   }   
   return map;
}
Run Code Online (Sandbox Code Playgroud)

只需向其传递一个 Collection,并让您的类实现 toString() 即可返回名称。多态性会解决这个问题。

  • 由于这仅适用于“toString()”作为获取索引键的函数,因此它不是一个非常好的通用解决方案,并且显然不适用于对象的任何任意属性。反射解决方案更糟糕,并且在重构时不会出现编译器错误。 (2认同)