哈希映射的设计问题?
有一个哈希映射的需求,就是将 若干维度
映射到 唯一值
(暂不考虑碰撞)
即 f(a,b,c....)=uniqueId
如果只是实现这个,那么我选择一个 性能以及冲突少的 hash 算法即可,可是还有另外一个需求:
假如我现在有 如下映射:
f(a, b) = u1
f(a, c) = u2
f(x, y) = v1
前提:f(a, b) != f(b, a)
如果我想实现 f(a) = [u1, u2] ,即 映射出来 以 a 为前缀的所有 映射结果,有没有比较好的方式?
目前想到的:
方式一:
根据 前缀 a 查询出 所有以 a 为前缀的 结果(即 a,b a,c),然后再分别 以这个结果去映射
方式二:
事先定义出我有查询 a 前缀的需求,那么在 f 这个映射函数上做手脚,即 如果输入 f(a, b),那么就产生 f(a), f(a, b)的映射并存储关联;如果输入f(a, c)就产生 f(a), f(a, c)的结果进行存储,那么再查询 f(a)时,就能以 f(a)的映射值查询出 之前关联的所有 f(a,b), f(a, c)的映射集合了
还有其他比较好的方式吗?
回答:
在 Java 中可以使用一个 Map 对象来实现哈希映射表,key 是一个包含所有维度的复合键对象,value 则是对应的唯一值。
对于第二个需求,可以使用 Java 8 中引入的 Stream API,结合 Lambda 表达式来实现。
具体的实现步骤如下:
1、定义一个包含所有维度的复合键类(可以使用 Java Bean 或者普通的 POJO 类)。
2、实现复合键类的 hashCode 和 equals 方法,以确保哈希映射表的正确性。
3、定义一个 Map 对象来维护哈希映射表。
4、查询以某个维度为前缀的所有映射结果时,使用 Stream API 进行过滤和映射。
下面是一个示例代码:
import java.util.*;import java.util.stream.*;
class Dimension {
private String a, b, c;
// Getters and setters omitted for brevity.
@Override
public int hashCode() {
return Objects.hash(a, b, c);
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof Dimension)) {
return false;
}
Dimension other = (Dimension)obj;
return Objects.equals(a, other.a) &&
Objects.equals(b, other.b) &&
Objects.equals(c, other.c);
}
}
public class HashMapDemo {
public static void main(String[] args) {
Map<Dimension, String> hashMap = new HashMap<>();
hashMap.put(new Dimension() {{ setA("a"); setB("b"); }}, "u1");
hashMap.put(new Dimension() {{ setA("a"); setC("c"); }}, "u2");
hashMap.put(new Dimension() {{ setA("x"); setB("y"); }}, "v1");
String[] result = hashMap.entrySet().stream()
.filter(entry -> Objects.equals(entry.getKey().getA(), "a"))
.map(Map.Entry::getValue)
.toArray(String[]::new);
System.out.println(Arrays.toString(result)); // 输出 [u1, u2]
}
}
回答:
我跟楼上想法类似,但更偏向于直接对象封装。
@Getter
@EqualsAndHashCode(of = "a")
public class Demo {
private String a;
private String b;
private int innerHash;
public Demo(String a, String b) {
this.a = a;
this.b = b;
this.innerHash = Objects.hash(a, b);
}
public static void main(String[] args) {
Demo ab = new Demo("a", "b");
Demo ac = new Demo("a", "c");
Demo ba = new Demo("b", "a");
Demo xy = new Demo("x", "y");
Map<String, List<Demo>> map = Arrays.asList(ab, ac, ba, xy)
.stream()
.collect(Collectors.groupingBy(Demo::getA));
List<Integer> hashs = map.get("a").stream().map(Demo::getInnerHash).collect(Collectors.toList());
System.out.println("a#hashs = " + hashs);
System.out.println("b#hashs = " + hashs);
}
}
以上是 哈希映射的设计问题? 的全部内容, 来源链接: utcz.com/p/945007.html