哈希映射的设计问题?

有一个哈希映射的需求,就是将 若干维度  映射到  唯一值(暂不考虑碰撞)
即 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

