多键Hashmap

时间:2015-09-22 11:25:50

标签: java

最近我接受了一次采访,以便在DS中保存大量的员工详细信息。

我将解决方案作为Hashmap以emp Id为关键。

后续问题是用户是否想要根据名称进行搜索如何实现它。我建议使用emp名称作为密钥,并保存所有与Arraylist同名的员工。

下一个跟进问题很棘手,需要创建一个地图,用户可以根据emp Id或emp名称进行搜索。如何在地图中实现这个?

以内存有效的方式实现它。

4 个答案:

答案 0 :(得分:1)

这是一个肮脏的解决方案 (是的 - 非常脏,从不在生产中执行!),但是如果密钥属于不同类型且一个是不是另一个的子类型(例如array(1) { ["booking"]=> array(18) { ["car_id"]=> string(1) "7" ["car_slug"]=> string(19) "audi-r8-v10-spyder1" ["vehicle"]=> string(16) "Aston Martin DB9" ["start_location"]=> string(20) "premiere-velocity-hq" ["start_date"]=> string(8) "23/09/15" ["start_time_hour"]=> string(2) "10" ["start_time_min"]=> string(2) "00" ["return_location"]=> string(18) "birmingham-airport" ["end_date"]=> string(8) "24/09/15" ["end_time_hour"]=> string(2) "10" ["end_time_min"]=> string(2) "00" ["discount"]=> string(0) "" ["start_location_name"]=> string(20) "Premiere Velocity HQ" ["return_location_name"]=> string(18) "Birmingham Airport" ["start_date_time"]=> string(16) "23/09/15 at 1000" ["return_date_time"]=> string(16) "24/09/15 at 1000" ["total_days"]=> int(1) ["total_price"]=> string(8) "£744.00" } } long)。按两个键放置每个员工,并使用提供的密钥获取Stringid

name

在生产代码中,我会使用两个单独的地图或自定义词典类。

答案 1 :(得分:1)

这是一个非常容易回答的问题:只需将ID转换为字符串并将员工存储两次 - 一次在名称下,再次在id-as-string下。

您使用List作为值的想法很好 - 对于ID,列表的大小为1。

请注意,最好使用两张地图,因为每个ID只有一名员工,而且您不必将大小为1的列表作为退化案例处理,所以:

Map<Integer, Employee> employeesById;
Map<String, Set<Employee>> employeesByName;

特别注意,只使用一张地图就不会占用更少的内存。实际上,您将使用比将员工存储在ID键和名称密钥的单独映射中更多的内存。

答案 2 :(得分:0)

执行此操作的一种方法是创建一个Key对象,可以通过名称或ID进行搜索:

public enum KeyType {
    ID, NAME;
}

public class SearchKey {
    private KeyType keyType;
    private String value;

    // constructor and getters snipped for brevity's sake

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        SearchKey searchKey = (SearchKey) o;

        return keyType == searchKey.keyType && value.equals(searchKey.value);

    }

    @Override
    public int hashCode() {
        int result = keyType.hashCode();
        result = 31 * result + value.hashCode();
        return result;
    }

public class Directory {
    private Map<SearchKey, Set<Employee>> directory = new HashMap<>();

    public void addEmployee(Employee e) {
        // Add search by id
        directory.put
            (new SearchKey(KeyType.ID, e.getId()), Collections.singleton(e));

        // Add search by name
        SearchKey searchByName = new SearchKey(KeyType.NAME, e.getName());
        Set<Employee> employees = directory.get(searchByName);
        if (employees == null) {
            employees = new HashSet<>();
            directory.put(searchByName, employees);
        }
        employees.add(e);
    }

    public Employee getById (String id) {
        // Assume that the ID is unique
        return directory.get(new SearchKey(KeyType.ID, id)).iterator().next();
    }

    public Set<Employee> getByName (String name) {
        return directory.get(new SearchKey(KeyType.NAME, name));
    }
}

答案 3 :(得分:0)

我想出了一个解决方案。请发表您的建议。

步骤1:使用emp id作为键和emp对象作为值来形成hashmap。

步骤2:对于相同的名称,创建一个与名称Ex匹配的emp id列表:name ='XYZ'id = {101,102,103,...}

步骤3:将此名称作为键和arraylist作为值插入到同一个地图

这里我们没有两次存储完整的员工详细信息。只是想保持名称和身份之间的关系。所以相对来说它可以节省内存。