树图中缺少键值对
Missing Key value pair in Tree Map
我正在尝试使用 TreeMap 解决编程问题,这导致我 post 这个问题。
我定义了一个以 (Int,Int) 为键,以字符串为值的 treeMap,根据元组的第一个元素定义了 treeMap 顺序。
我插入了两个不同的元素 Key,但最终的 treeMap 只包含一个 element.Is 这是 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 中尝试了相同的实现,但它报告地图大小为 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(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
为了给出一个准确的答案,我想说的是,与 Java 的 TreeMap
不同,scala.collection.mutable.TreeMap
使用提供的 Ordering
来确定相等性而不是使用 ==
。这还有其他一些有趣的结果。使用您问题中的 a
:
a.contains((9, 0)) // true
a((9, -1000)) // "value-2"
的确,Ordering 有一个方法 equiv
for determining whether two things are equal in an ordering. While this method is not used in the TreeMap implementation,它显示了依赖 Ordering
作为真理来源的哲学,而不是不太灵活的 ==
.
我正在尝试使用 TreeMap 解决编程问题,这导致我 post 这个问题。
我定义了一个以 (Int,Int) 为键,以字符串为值的 treeMap,根据元组的第一个元素定义了 treeMap 顺序。 我插入了两个不同的元素 Key,但最终的 treeMap 只包含一个 element.Is 这是 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 中尝试了相同的实现,但它报告地图大小为 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(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
为了给出一个准确的答案,我想说的是,与 Java 的 TreeMap
不同,scala.collection.mutable.TreeMap
使用提供的 Ordering
来确定相等性而不是使用 ==
。这还有其他一些有趣的结果。使用您问题中的 a
:
a.contains((9, 0)) // true
a((9, -1000)) // "value-2"
的确,Ordering 有一个方法 equiv
for determining whether two things are equal in an ordering. While this method is not used in the TreeMap implementation,它显示了依赖 Ordering
作为真理来源的哲学,而不是不太灵活的 ==
.