首页 > 解决方案 > 通过 ID 将数组索引到映射的通用类

问题描述

我的代码中有很多情况,我必须使用 Hibernate 从数据库访问数据并将结果作为列表接收。大多数情况下,这些数据是通过 ID 缓存和访问的。很明显,我必须将其转换为 Map 以获得快速结果,因为每次迭代它都是 O(n) 的噩梦。

问题不在于如何做到这一点,这个过程相当简单:

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

我想知道的是,普通 Java 库中是否已经有此功能,因为我必须一遍又一遍地重复此代码,并且希望将其减少到一行。这似乎是一个常见的用例。

标签: javadictionary

解决方案


如果 Hibernate 的内置功能已经可以为您解决这个问题,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()));
    }
}

推荐阅读