Har*_*ald 7 java hashmap symbolic-math polynomials
在尝试对多项式进行建模时,特别是它们的乘法,我遇到了以下问题.在乘法期间,两个多项式的单个单项式相乘,当然可以发生我有(3x ^ 2 y + 5x y ^ 2)*(x + y).结果包含3x ^ 2 y ^ 2和5 x ^ 2 y ^ 2,我想通过添加立即组合.
当然,我想使用单项式的部分x ^ 2 y ^ 2作为(哈希)映射中的关键字来添加不同的系数(在示例中为3和5).但是我设想的单项式对象自然也应该包含系数,该系数不应该是地图键的一部分.
当然,我可以写单项对象的equals/hashcode,使它们忽略系数.但这感觉错了,因为数学上单项式显然只等于另一个,如果系数相等的话.
为中间操作引入无系数单项式对象也看起来不正确.
我没有使用地图,而是使用列表并使用二进制搜索和一个忽略系数的专用比较器.
如果没有使用不使用密钥'equals/hashcode的地图,而是使用专用的地图,那么有没有更好的想法如何融合单项式?
由于 JDK 实现[Linked]HashMap不允许您覆盖equals/hashCode实现,因此唯一的其他方法是:
一个像这样的包装对象:
class A {
private final String fieldA; // equals/hashCode based on that field.
private final String fieldB; // equals/hashCode based on that field.
}
class B {
private A a;
public int hashCode() {return a.fieldA.hashCode();}
public boolean equals(Object o) {... the same ... }
}
Map<B, Value> map = new HashMap<B, Value>();
map.put(new B(new A("fieldA", "fieldB")), new Value(0));
Run Code Online (Sandbox Code Playgroud)
好吧,有更多的吸气剂/构造函数。
这可能很烦人,而且可能存在一些库(如 Guava),它允许给定一个 equals/hashCode 方法,就像给一个Comparatorto 一样TreeMap。
您将在下面找到一个示例实现,它指出如何装饰现有地图。
将 aTreeMap与特定的Comparator. 另一个答案指出了这一点,但我会说您需要正确定义 a ,Comparator因为这可能会导致问题:如果您的compareTo方法在达到相等时返回 0,在其他情况下返回 1,这意味着没有自然排序。您应该尝试找到一个,或者使用包装器对象。
如果你想接受挑战,你可以使用委托/装饰来创建一个基本的实现HashMap(这可能是另一种地图,比如LinkedHashMap):
public class DelegatingHashMap<K,V> implements Map<K,V> {
private final BiPredicate<K,Object> equalsHandler;
private final IntFunction<K> hashCodeHandler;
private final Map<Wrapper<K>,V> impl = new HashMap<>();
public DelegatingHashMap(
BiPredicate<K,Object> equalsHandler,
IntFunction<K> hashCodeHandler
) {
this.equalsHandler = requireNonNull(equalsHandler, "equalsHandler");
this.hashCodeHandler= requireNonNull(hashCodeHandler, "hashCodeHandler");
}
public Object get(K key) {
Wrapper<K> wrap = new Wrapper<>(key);
return impl.get(wrap);
}
...
static class Wrapper<K2> {
private final K2 key;
private final BiPredicate<K> equalsHandler;
private final IntFunction<K> hashCodeHandler;
public int hashCode() {return hashCodeHandler.apply(key);}
public boolean equals(Object o) {
return equalsHandler.test(key, o);
}
}
}
Run Code Online (Sandbox Code Playgroud)
以及使用地图的代码:
DelegatingHashMap<String, Integer> map = new DelegatingHashMap<>(
(key, old) -> key.equalsIgnoreCase(Objects.toString(o, "")),
key -> key.toLowerCase().hashCode()
);
map.put("Foobar", 1);
map.put("foobar", 2);
System.out.println(map); // print {foobar: 2}
Run Code Online (Sandbox Code Playgroud)
但也许最好的(对于内存)是重写HashMap直接使用处理程序而不是包装器。