【问题标题】:Missing Key value pair in Tree Map树图中缺少键值对
【发布时间】:2019-02-09 07:07:58
【问题描述】:

我正在尝试使用 TreeMap 解决编程问题,这导致我发布了这个问题。

我定义了一个以 (Int,Int) 为键,以字符串为值的 treeMap,根据元组的第一个元素定义了 treeMap 排序。 而且我插入了两个不同Key的元素,但是最终的treeMap只包含一个元素。这是treeMap的定义行为吗

Scala 代码:(版本:2.12.3)

val a = scala.collection.mutable.TreeMap[(Int, Int), String]()(Ordering.by(x => x._1))
a.put((9, 21), "value-1")
a.put((9, 10), "value-2")
println(a.size) // 1

我在 java 中尝试过相同的实现,但它报告 Map Size 为 2 这是我的java代码:

如果我遗漏了一些东西,有人可以建议

import java.util.Comparator;
import java.util.TreeMap;

public class JavaTreeMapTest {

    public static void main(String[] args) {

        class Tuple {
            Integer a;
            Integer b;

            public Tuple(Integer a, Integer b) {
                this.a = a;
                this.b = b;
            }

        }
        Comparator<Tuple> testComparator = new Comparator<Tuple>() {

            @Override
            public int compare(Tuple arg0, Tuple arg1) {
                if (arg0.a > arg1.a) {
                    return arg0.a;
                } else
                    return arg1.a;
            }

        };

        TreeMap<Tuple, String> tm = new TreeMap<Tuple, String>(testComparator);
        tm.put(new Tuple(100, 100), "value-1");
        tm.put(new Tuple(100, 101), "value-2");

        System.out.println(tm.size()); //2

    }
}

【问题讨论】:

  • Ordering.by() 是不需要的,因为Tuple2[Int,Int] 的自然顺序已经是_1。二级订单密钥为_2

标签: scala treemap


【解决方案1】:

问题在于您的订购。如果你像这样使用它:Ordering.by(x =&gt; x._1),TreeMap 将只考虑第一个元素来计算相等性。 因此,(9, 21)(9, 21) 将被视为相等。

一种解决方案是先按第一个元素排序,然后再按第二个元素排序。你可以通过返回一个元组来做到这一点: Ordering.by(x =&gt; (x._1, x._2))

但由于您已经在使用元组,您可以将其简化为:

Ordering.by(x => x)

Ordering.by(identity)

您可以省略它,因为按身份排序是默认设置。

总结一下:

val a = scala.collection.mutable.TreeMap[(Int, Int), String]()
a.put((9, 21), "value-1")
a.put((9, 10), "value-2")
println(a.size) // 2

【讨论】:

  • 我认为您的意思是“对于 (9, 21) 和 (9, 10)”和“密钥将是 9 ”。此外,更准确地说,TreeMap 在该排序下将(9, 21) 视为等于(9, 10); Map 中的键实际上不是 9,您可以通过在地图上调用 .keys 来确定。 (虽然这里有一些尴尬的术语重载,因为 9 是 Ordering 中的关键,但不是 Map...)
【解决方案2】:

为了给出准确的答案,我想说的是,与 Java 的 TreeMap 不同,scala.collection.mutable.TreeMap 使用提供的 Ordering 来确定相等性,而不是使用 ==。这还有其他一些有趣的结果。使用您问题中的a

a.contains((9, 0)) // true
a((9, -1000)) // "value-2"

确实,Ordering 有一个方法equiv 用于确定两个事物在排序中是否相等。虽然TreeMap implementation 没有使用这种方法,但它显示了依赖Ordering 作为事实来源而不是不太灵活的== 的哲学。

【讨论】:

    猜你喜欢
    • 2022-06-30
    • 2020-10-21
    • 2020-06-04
    • 2020-09-09
    • 1970-01-01
    • 2018-10-13
    • 2021-09-24
    • 2013-10-21
    • 1970-01-01
    相关资源
    最近更新 更多