Java 为什么在打印TreeMap中的值时会得到一个空值列表?
我是Java新手,正在使用这个站点上的TreeMap代码示例,但是当我尝试遍历TreeMap时,我得到了一个空值列表,但是当我直接打印映射时,我可以看到键/值对。我如何纠正这一点Java 为什么在打印TreeMap中的值时会得到一个空值列表?,java,Java,我是Java新手,正在使用这个站点上的TreeMap代码示例,但是当我尝试遍历TreeMap时,我得到了一个空值列表,但是当我直接打印映射时,我可以看到键/值对。我如何纠正这一点 import java.util.*; public class Testing { public static void main(String[] args) { HashMap<String,Double> map = new HashMap<String,Doubl
import java.util.*;
public class Testing {
public static void main(String[] args) {
HashMap<String,Double> map = new HashMap<String,Double>();
ValueComparator1 bvc = new ValueComparator1(map);
TreeMap<String,Double> sorted_map = new TreeMap<String,Double>(bvc);
map.put("A",99.5);
map.put("B",67.4);
map.put("C",67.4);
map.put("D",67.3);
System.out.println("unsorted map: "+map);
sorted_map.putAll(map);
System.out.println("results: "+sorted_map);
for(String key: sorted_map.keySet())
{
System.out.println(sorted_map.get(key)); //null values-Why?
}
}
}
class ValueComparator1 implements Comparator<String> {
Map<String, Double> base;
public ValueComparator1(Map<String, Double> base) {
this.base = base;
}
// Note: this comparator imposes orderings that are inconsistent with equals.
public int compare(String a, String b) {
if (base.get(a) >= base.get(b)) {
return -1;
} else {
return 1;
} // returning 0 would merge keys
}
}
它不起作用,因为当给定相同的键时,比较器不会返回0,例如compareA,A。将其更改为
public int compare(String a, String b) {
Double va = base.get(a);
Double vb = base.get(b);
if(va > vb) {
return -1;
} else if(va < vb) {
return 1;
} else {
return a.compareTo(b);
}
}
它会工作。它不工作,因为当给定相同的键时,比较器不会返回0,例如compareA,A。将其更改为
public int compare(String a, String b) {
Double va = base.get(a);
Double vb = base.get(b);
if(va > vb) {
return -1;
} else if(va < vb) {
return 1;
} else {
return a.compareTo(b);
}
}
很抱歉,你的例子有点颠倒了。您将键放入已排序的映射树映射中,然后使用值作为键,即通过值进行比较。看起来你想处理有一个键和一个值的对象,所以这里有一些你可能需要考虑的东西。这无疑是处理复合概念的OOP方法,比如您正在使用地图建模的概念
class Pair implements Comparable<Pair> {
String value;
double key;
Pair(String value, double key) {
this.value = value;
this.key = key;
}
public int compareTo(Pair p) {
return Double.compare(key, p.key);
}
public String toString(Pair p) {
return value + "," + key;
}
}
static void main(String[] args) {
Set<Pair> unsortedSet = new HashSet<Pair>();
unsortedSet.add(new Pair("A", 99.5));
unsortedSet.add(new Pair("B", 67.4));
unsortedSet.add(new Pair("C", 67.4));
unsortedSet.add(new Pair("D", 67.3));
Set<Pair> sortedSet = new TreeSet<Pair>();
sortedSet.add(new Pair("A", 99.5));
sortedSet.add(new Pair("B", 67.4));
sortedSet.add(new Pair("C", 67.4));
sortedSet.add(new Pair("D", 67.3));
System.out.println("Unsorted set: " + unsortedSet);
System.out.println("Sorted set: " + sortedSet);
for (Pair pair : sortedSet) {
System.out.println(pair);
}
}
对不起,你的例子有点颠倒了。您将键放入已排序的映射树映射中,然后使用值作为键,即通过值进行比较。看起来你想处理有一个键和一个值的对象,所以这里有一些你可能需要考虑的东西。这无疑是处理复合概念的OOP方法,比如您正在使用地图建模的概念
class Pair implements Comparable<Pair> {
String value;
double key;
Pair(String value, double key) {
this.value = value;
this.key = key;
}
public int compareTo(Pair p) {
return Double.compare(key, p.key);
}
public String toString(Pair p) {
return value + "," + key;
}
}
static void main(String[] args) {
Set<Pair> unsortedSet = new HashSet<Pair>();
unsortedSet.add(new Pair("A", 99.5));
unsortedSet.add(new Pair("B", 67.4));
unsortedSet.add(new Pair("C", 67.4));
unsortedSet.add(new Pair("D", 67.3));
Set<Pair> sortedSet = new TreeSet<Pair>();
sortedSet.add(new Pair("A", 99.5));
sortedSet.add(new Pair("B", 67.4));
sortedSet.add(new Pair("C", 67.4));
sortedSet.add(new Pair("D", 67.3));
System.out.println("Unsorted set: " + unsortedSet);
System.out.println("Sorted set: " + sortedSet);
for (Pair pair : sortedSet) {
System.out.println(pair);
}
}
因为比较器从不返回0,所以TreeMap.get不起作用。仍然可以像这样迭代树映射条目
for (Entry<String, Double> e : sorted_map.entrySet()) {
System.out.println(e);
}
因为比较器从不返回0,所以TreeMap.get不起作用。仍然可以像这样迭代树映射条目
for (Entry<String, Double> e : sorted_map.entrySet()) {
System.out.println(e);
}
亚当·克拉姆的密码非常重要。为了更详细地解释这一点,当您调用sorted_map.getkey时,它会转到java.util.TreeMap class',getEntryUsingComparator方法,因为您已经显式地设置了比较器。这个方法看起来像
final Entry<K,V> getEntryUsingComparator(Object key) {
K k = (K) key;
Comparator<? super K> cpr = comparator;
if (cpr != null) {
Entry<K,V> p = root;
while (p != null) {
int cmp = cpr.compare(k, p.key);
if (cmp < 0)
p = p.left;
else if (cmp > 0)
p = p.right;
else
return p;
}
}
return null;
}
亚当·克拉姆的密码非常重要。为了更详细地解释这一点,当您调用sorted_map.getkey时,它会转到java.util.TreeMap class',getEntryUsingComparator方法,因为您已经显式地设置了比较器。这个方法看起来像
final Entry<K,V> getEntryUsingComparator(Object key) {
K k = (K) key;
Comparator<? super K> cpr = comparator;
if (cpr != null) {
Entry<K,V> p = root;
while (p != null) {
int cmp = cpr.compare(k, p.key);
if (cmp < 0)
p = p.left;
else if (cmp > 0)
p = p.right;
else
return p;
}
}
return null;
}
这仅仅是需要的吗?因为我所有的钥匙在示例中都是不同的。我仍然不明白这个编辑背后的原因。顺便说一句,这是必要的,因为当你调用getA时,地图会查看A的条目,你原来的比较器会说键不相等,所以它不会返回该条目。这是必需的吗?因为我所有的钥匙在示例中都是不同的。我仍然不明白这个编辑背后的原因。顺便说一句,这是必要的,因为当你调用getA时,映射查看A的条目,你原来的比较器说键不相等,所以它不会返回该条目。与equals的一致性当然是理想的,但树映射并不总是需要的。根据文档,即使排序与equals不一致,已排序映射的行为也是定义良好的;它只是没有遵守Map接口的一般约定。与equals的一致性当然是理想的,但TreeMap并不总是需要。根据文档,即使排序与equals不一致,已排序映射的行为也是定义良好的;只是没有遵守地图界面的总合同。