通过ID将数组索引到地图的通用类

时间:2018-08-03 14:39:59

标签: java dictionary

我的代码中有很多情况,我必须使用Hibernate从数据库访问数据并以列表形式接收结果。通常,此数据通过ID进行缓存和访问。显然,我必须将其转换为Map才能获得快速结果,因为每次对其进行迭代都是一场O(n)的噩梦。

问题不是该怎么做,这个过程很简单:

Map<Integer, ProjectEntry> projectEntries = new HashMap<>();
for (ProjectEntry p : projectService.listProjectEntries()) {
    projectEntries.put(p.getId(), p);
}

我想知道的是,常见的Java库中是否已经有此功能,因为我不得不一遍又一遍地重复此代码,并且希望将其简化为一行。似乎是一个如此常见的用例。

3 个答案:

答案 0 :(得分:1)

如果Hibernate的内置功能已经可以解决您的问题,那么answer by sajib可能是正确的选择。

否则,可以使用Java标准API的内置功能-即使用适当的Collector创建这样的地图:

Map<Integer, ProjectEntry> map = list.stream().collect(
    Collectors.toMap(ProjectEntry::getId, Function.identity()));

但是,这当然很笨拙。您可以将其拉入实用程序方法。而且,该实用程序方法可能相当通用,用上面的代码包装了上面的行,并为ProjectEntry类做了较小的专门化。

一个小例子:

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

public class MapById
{
    static class ProjectEntry
    {
        int getId()
        {
            return System.identityHashCode(this);
        }
    }
    public static void main(String[] args)
    {
        List<ProjectEntry> list = new ArrayList<ProjectEntry>();
        list.add(new ProjectEntry());
        list.add(new ProjectEntry());
        list.add(new ProjectEntry());

        System.out.println(createMapFromIds(list));
    }

    private static Map<Integer, ProjectEntry> createMapFromIds(
        Collection<? extends ProjectEntry> collection)
    {
        return createMap(collection, ProjectEntry::getId);
    }

    private static <K, T> Map<K, T> createMap(
        Collection<? extends T> collection, 
        Function<? super T, ? extends K> keyMapper)
    {
        return collection.stream().collect(
            Collectors.toMap(keyMapper, Function.identity()));
    }
}

答案 1 :(得分:0)

您可以尝试以下操作:

Query query=session.createSQLQuery(sql);
List<Map<String,Object>> dataList = query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list(); 

答案 2 :(得分:0)

数据库引擎在休眠状态下有缓存。因此地图似乎是另一个缓存层。仍然可能在休眠会话之外,并且没有O / R映射,因此效率更高。

Map<Integer, ProjectEntry> projectEntries = 
        projectService.listProjectEntries().stream()
            .collect(Collectors.toMap(ProjectEntry::getId, Function.identity()));

如果您需要许多地图,请重新考虑是否涉及DOM,文档对象模型

  • 有许多实体形成一个大对象图(可能是“ Project”),或多或少地形成了一个 document ;
  • 仅引用主数据,不引用其他项目;
  • 仅在项目内部查询;
  • 处理缓慢,涉及在多个分层实体上的级联更新。

在这种情况下,数据库可能不是保存“文档”的最佳方法。在一个项目中,我们使用 JAXB 将该图转换为XML文档,并将该文档作为GZipped压缩XML的BLOB存储在单个表中。然后,文档对象模型可以具有一个顶部元素,其中包含列表,尤其是地图。

它使处理变得更加容易和快捷。

JPA隐藏了很多东西,但是如果您需要很多地图,请重新考虑体系结构。