Java 允许分别提供equals比较器和散列函数的映射

Java 允许分别提供equals比较器和散列函数的映射,java,hashmap,symbolic-math,polynomials,Java,Hashmap,Symbolic Math,Polynomials,在尝试对多项式建模时,特别是对其乘法建模时,我遇到了以下问题。在乘法过程中,两个多项式的单个单项式相乘,当然,我有(3x^2y+5x y^2)*(x+y)。结果包含3x^2y^2和5x^2y^2,我想立即通过加法将其合并 当然,我想使用单项式的x^2 y^2部分作为(散列)映射中的一个键,来相加不同的系数(示例中为3和5)。但是我设想的单项式对象自然也应该包含系数,它应该而不是是map键的一部分 当然,我可以编写单项式对象的equals/hashcode,这样它们就可以忽略系数。但这感觉非常错误

在尝试对多项式建模时,特别是对其乘法建模时,我遇到了以下问题。在乘法过程中,两个多项式的单个单项式相乘,当然,我有(3x^2y+5x y^2)*(x+y)。结果包含3x^2y^2和5x^2y^2,我想立即通过加法将其合并

当然,我想使用单项式的x^2 y^2部分作为(散列)映射中的一个键,来相加不同的系数(示例中为3和5)。但是我设想的单项式对象自然也应该包含系数,它应该而不是是map键的一部分

当然,我可以编写单项式对象的equals/hashcode,这样它们就可以忽略系数。但这感觉非常错误,因为从数学上讲,一个单项式显然只有在系数相等的情况下才等于另一个单项式

为中间操作引入一个无系数的单项式对象也不合适

我可以使用一个列表和一个二进制搜索,并使用一个忽略系数的专用比较器,而不是使用映射


除了实现一个不使用equals/hashcode键的映射,而是一个专用的映射之外,还有什么更好的方法来融合单项式吗?

因为
[Linked]HashMap
的JDK实现不允许覆盖
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));
    
    以及使用地图的代码:

    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}
    
    DelegatingHashMap=newdelegatinghashmap(
    (key,old)->key.equalsIgnoreCase(Objects.toString(o,“”),
    key->key.toLowerCase().hashCode()
    );
    地图放置(“Foobar”,1);
    地图放置(“foobar”,2);
    System.out.println(映射);//打印{foobar:2}
    

    但是(对于内存而言)最好的方法可能是重写
    HashMap
    ,直接使用处理程序而不是包装器。

    您可以使用带有自定义比较器的
    TreeMap


    TreeMap(Comparator我认为最好将单项式分为两部分:系数和变量。这样,您可以使用地图中的变量部分作为键,将系数作为值(然后可以向上更新)

    所有这些代码都应该是
    多项式
    对象中的实现细节


    我不知道你为什么认为一个没有系数的单项式看起来不合适。如果你不想,你不必把对象暴露在外面。但是在你的
    多项式上设置getter来获取每个单项式的系数可能是一个不错的方法。

    考虑使用
    树形图,这是一个
    分类图d因此也是一个
    映射
    。您可以向其构造函数提供一个
    比较器
    。排序后的映射将使用该
    比较器
    对映射键进行排序。但重要的是,对于您的情况,如果
    比较器
    返回0,它将消耗相等的键。在您的情况下,将需要一个
    比较器
    坚持平等,如果你不小心,这可能会给你带来麻烦


    另一种选择是引入另一个类,该类充当
    单项式的适配器
    ,并可用作具有所需属性的映射键。

    好吧,没有系数的单项式看起来是错误的,因为没有系数,它就不再是数学意义上的单项式。树映射依赖于对单项式进行二进制排序虽然我可以提供所需的比较器,但我宁愿使用一个排序的二进制数组。我认为开销更小,性能应该是可比的。使用包装器当然是可能的,但是我认为这太多的开销,如果不是性能的话(不要过早优化)。,但在概念上,我认为这太多了。然后尝试使用树形图,但这应该是一个树形图,或者您不应该忘记对系数求和:)
    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}
    
    TreeMap(Comparator<? super K> comparator)