我创建了一个由两部分组成的组合键:mainID和sendaryID.当我需要插入一个值时,我希望能够同时使用这两个部分.但是,我希望能够以两种方式检索值: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;
    }
}

推荐答案

您可以使用嵌套映射来处理此问题.我已经创建了一个单独的类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]
    }
}

Java相关问答推荐

表格栏上的事件过滤器在PFA中不起作用

如何用javac编译Java类,即使对像java.lang.*这样的基本类也没有任何依赖关系?

基于仅存在于父级中的字段查询子文档?

使用Java Streams API比较两个不同的Java集合对象和一个公共属性

从技术上讲,OPC UA客户端是否可以通过转发代理将请求通过 tunel 发送到OPC UA服务器?

neo4j java驱动程序是否会在错误发生时自动回滚事务?

Java中是否有某种类型的池可以避免重复最近的算术运算?

如何使用Maven和Spring Boot将构建时初始化、跟踪类初始化正确传递到本机编译

为什么JAVA&S清洁器使用链表而不是并发HashSet?

由于我在Main方法中关闭了 scanner ,但在该方法中创建了一个新的 scanner ,因此出现了错误

虚拟线程应该很快消亡吗?

Instancio未在日志(log)中显示测试失败消息

有谁能帮我修一下这个吗?使输出变得更加整洁

如何在Java中的重写方法参数中强制(Enum)接口实现?

TinyDB问题,无法解析符号';上下文&

如何在Spring Boot Auth服务器上正确配置CORS?

让标签占用JavaFX中HBox的所有可用空间

带有提取器的JavaFXObservableList会根据侦听器的存在而改变行为

在java中使用SevenZip.openArchive方法后无法删除文件

Java ModbusRTU写寄存器