1

私はJavaを初めて使用し、このサイトにあるTreeMapコードの例を使用していますが、TreeMapを反復処理しようとすると、null値のリストが表示されますが、マップを直接印刷すると、キーと値のペアが表示されます。これを修正するにはどうすればよいですか?

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
    }
}
4

4 に答える 4

6

同一のキー(compare( "A"、 "A")など)を指定した場合、コンパレータは0を返さないため、機能しません。に変更します

    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);
        }
    }

そしてそれは動作します。

于 2013-01-21T03:38:17.747 に答える
3

申し訳ありませんが、あなたの例は少し逆さまです。ソートされたマップ(ツリーマップ)にキーを配置しますが、値で比較するという意味で、値をキーとして使用します。キーと値を持つオブジェクトを処理しようとしているように見えるので、ここで検討する必要があるかもしれません。これは確かに、マップを使用してモデリングしているような「複合」概念を処理するための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);
    }
}
于 2013-01-21T03:42:57.840 に答える
1

コンパレータが0を返すことはないため、TreeMap.get()は機能しません。それでも、このようなTreeMapエントリを反復処理できます

    for (Entry<String, Double> e : sorted_map.entrySet()) {
        System.out.println(e);
    }

プリント

A=99.5
C=67.4
B=67.4
D=67.3
于 2013-01-21T03:50:04.883 に答える
0

AdamCrumeのコードは非常に重要です。これについて詳しく説明すると、コンパレータを明示的に設定しているため、を呼び出すと、クラス'、メソッドにsorted_map.get(key)移動しjava.util.TreeMapます。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;
    }

値コンパレータのメソッドにキーの比較があるため、エントリはnullになり、次のように実装されているcompareため、値もnullになります。map.get

 public V get(Object key) {
        Entry<K,V> p = getEntry(key);
        return (p==null ? null : p.value);
    }
于 2013-01-21T03:57:26.847 に答える