我有一个树集。如何找到树集的根元素:
TreeSet<Integer> ts = new TreeSet<Integer>();
ts.add(8);
ts.add(3);
ts.add(8);
ts.add(1);
ts.add(0);
ts.add(4);
ts.add(7);
答案 0 :(得分:2)
如果你绝对需要(欲望?)知道当前的根值是什么,你可以使用反射。
注意: TreeSet
和TreeMap
的内部实施可能会发生变化,以下代码将失败。代码已经过JDK 1.8u91测试
此外,如果存在安全管理器,代码将失败并显示SecurityException
。
以下两种辅助方法可用于为您提供TreeSet
和TreeMap
的根。
@SuppressWarnings("unchecked")
public static <E> E getTreeRoot(TreeSet<E> ts) {
try {
Field mField = TreeSet.class.getDeclaredField("m");
mField.setAccessible(true);
return getTreeRoot((TreeMap<E, Object>) mField.get(ts));
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new IllegalStateException("Internals of TreeSet has changed", e);
}
}
@SuppressWarnings("unchecked")
public static <K,V> K getTreeRoot(TreeMap<K,V> tm) {
try {
Field rootField = TreeMap.class.getDeclaredField("root");
rootField.setAccessible(true);
Map.Entry<K,V> root = (Map.Entry<K,V>) rootField.get(tm);
return (root == null ? null : root.getKey());
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new IllegalStateException("Internals of TreeMap has changed", e);
}
}
测试助手
private static void test(int... values) {
TreeSet<Integer> ts = new TreeSet<>();
System.out.println("Root is " + getTreeRoot(ts) + " for " + ts);
for (int v : values) {
ts.add(v);
System.out.println("Root is " + getTreeRoot(ts) + " for " + ts);
}
}
测试1 (有问题的值)
test(8, 3, 8, 1, 0, 4, 7);
Root is null for []
Root is 8 for [8]
Root is 8 for [3, 8]
Root is 8 for [3, 8]
Root is 3 for [1, 3, 8]
Root is 3 for [0, 1, 3, 8]
Root is 3 for [0, 1, 3, 4, 8]
Root is 3 for [0, 1, 3, 4, 7, 8]
测试2 (升序顺序中的图表中的值)
test(5, 15, 17, 18, 20, 22, 25, 27, 30);
Root is null for []
Root is 5 for [5]
Root is 5 for [5, 15]
Root is 15 for [5, 15, 17]
Root is 15 for [5, 15, 17, 18]
Root is 15 for [5, 15, 17, 18, 20]
Root is 15 for [5, 15, 17, 18, 20, 22]
Root is 15 for [5, 15, 17, 18, 20, 22, 25]
Root is 18 for [5, 15, 17, 18, 20, 22, 25, 27]
Root is 18 for [5, 15, 17, 18, 20, 22, 25, 27, 30]
测试3 (图表中降序顺序中的值)
test(30, 27, 25, 22, 20, 18, 17, 15, 5);
Root is null for []
Root is 30 for [30]
Root is 30 for [27, 30]
Root is 27 for [25, 27, 30]
Root is 27 for [22, 25, 27, 30]
Root is 27 for [20, 22, 25, 27, 30]
Root is 27 for [18, 20, 22, 25, 27, 30]
Root is 27 for [17, 18, 20, 22, 25, 27, 30]
Root is 22 for [15, 17, 18, 20, 22, 25, 27, 30]
Root is 22 for [5, 15, 17, 18, 20, 22, 25, 27, 30]
如您所见,根取决于插入的顺序。