如何仅使用部分键/ID(复合)高效返回映射的值?

问题描述 投票:0回答:1

我创建了一个包含两部分的复合键:mainId 和 secondaryId。当我需要插入值时,我希望能够使用这两个部分。但是,我希望能够通过两种方式检索一个值:1)使用两个部分仅返回一个值; 2) 仅使用 mainId 返回具有该 mainId 的值的列表。

我在下面的代码中实现了2)。然而,它看起来效率并不高。有更好的方法吗?

非常感谢!

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;

public class Main {
    public static void main(String[] args) {

        Map<CompositeId, String> map = new HashMap();

        map.put(new CompositeId("1", "1"), "val1");
        map.put(new CompositeId("1", "1"), "val2");
        map.put(new CompositeId("1", "2"), "val3");
        map.put(new CompositeId("2", "1"), "val4");

        // is there any way to do this more efficiently? //
        List<String> listValsWithMainIdEqualsOne = new ArrayList();
        List<CompositeId> listIdsWithMainIdEqualsOne = map.keySet().stream().filter(k -> k.getMainId().equals("1")).toList();
        listIdsWithMainIdEqualsOne.forEach(k -> listValsWithMainIdEqualsOne.add(map.get(k)));
        //////////////////////////////////////////////////

        assert map.get(new CompositeId("1", "1")).equals("val2");
        assert map.get(new CompositeId("1", "2")).equals("val3");
        assert listValsWithMainIdEqualsOne.contains("val2");
        assert listValsWithMainIdEqualsOne.contains("val3");
    }
}

class CompositeId {

    private String mainId;
    private String secondaryId;

    public CompositeId(String mainId, String secondaryId) {

        this.mainId = mainId;
        this.secondaryId = secondaryId;
    }

    @Override
    public boolean equals(Object o) {

        if (this == o) return true;

        if (o == null || getClass() != o.getClass()) return false;

        CompositeId compositeId = (CompositeId) o;

        if (!this.mainId.equals(compositeId.getMainId())) return false;

        if (compositeId.getSecondaryId() != null && !this.secondaryId.equals(compositeId.getSecondaryId())) return false;

        return true;
    }

    @Override
    public int hashCode() {
        return (mainId + secondaryId).hashCode();
    }

    public String getMainId() {

        return mainId;
    }

    public String getSecondaryId() {

        return secondaryId;
    }
}
java hashmap
1个回答
0
投票

您可以使用嵌套映射来处理此问题。我创建了一个单独的类

CompositeMap
并演示了相同的内容。

代码

public class CompositeKeys {
    private static class CompositeMap {
        private Map<String, Map<String,String>> M = new HashMap<>();

        public String put(String primary, String secondary, String value) {
            if (!M.containsKey(primary)) {
                M.put(primary, new HashMap<>());
            }

            return M.get(primary).put(secondary, value);
        }

        public String get(String primary, String secondary) {
            if (M.containsKey(primary)) {
                return M.get(primary).get(secondary);
            } else {
                return null;
            }
        }

        public List<String> get(String primary) {
            if (M.containsKey(primary)) {
                return M.get(primary).values().stream().toList();
            } else {
                return null;
            }
        }
    }

    public static void main(String[] args) {
        CompositeMap map = new CompositeMap();

        map.put("1", "1", "val1");
        map.put("1", "1", "val2");
        map.put("1", "2", "val3");
        map.put("2", "1", "val4");

        System.out.println(map.get("1", "1"));  // val2
        System.out.println(map.get("1", "2"));  // val3
        System.out.println(map.get("1"));       // [val2, val3]
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.