我创建了一个包含两部分的复合键: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;
}
}
您可以使用嵌套映射来处理此问题。我创建了一个单独的类
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]
}
}