树图中缺少键值对

时间:2019-02-09 07:07:58

标签: scala treemap

我正在尝试使用TreeMap解决编程问题,这使我不得不提出此问题。

我有一个以(Int,Int)作为我的键并以String作为值的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

    }
}

2 个答案:

答案 0 :(得分:4)

问题出在您的订购上。如果您这样使用它:Ordering.by(x => x._1),则TreeMap将仅考虑用于计算相等性的第一个元素。 因此,(9, 21)(9, 21)都被认为是相等的。

一种解决方案是先按第一个元素排序,然后再按第二个元素排序。您可以通过返回一个元组来做到这一点: Ordering.by(x => (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

答案 1 :(得分:4)

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

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

实际上,排序具有equiv方法,用于确定排序中两个事物是否相等。尽管TreeMap implementation中未使用此方法,但它显示了依靠Ordering作为真理的来源而不是不太灵活的==的哲学。