0

たくさんのMap<Integer, TreeSet<Double>>オブジェクトがあり、値を別のメソッドに渡しています。私はNoSuchElementExceptionそのメソッドを取得したので、デバッグを開始し、への呼び出しMap#values()がこの例外をスローすることを確認しました。しかし、値をループすると、すべての値が完全に出力されます。この問題の原因となっているコード スニペットは次のとおりです。

Map<Integer, TreeMultimap<String, Double>> kMap = Maps.newTreeMap();
for (int i = 0; i < 3; i++) {
    TreeMultimap<String, Double> treeMultimap = TreeMultimap.create();
    treeMultimap.putAll("a" + i, Lists.newArrayList(0.0, 0.06, 0.17, 0.23));
    treeMultimap.putAll("b" + i, Lists.newArrayList(0.0, 0.16, 0.34, 0.49));
    kMap.put(i, treeMultimap);
}

Map<Integer, TreeSet<Double>> rescaledKMap =
    Maps.transformEntries(kMap, ToRescaledValueMap(1.2));

Iterable<TreeSet<Double>> treeSets = rescaledKMap.values();

// Prints out each element correctly. No exception is thrown.
for (TreeSet<Double> set : treeSets)
    System.out.println(Joiner.on(',').join(set));

// NoSuchElementException thrown in getMeanPlot() before anything happens there.
TreeMap<Double, Double> mean_rescaledKMap = 
    getMeanPlot(rescaledKMap.values());

署名はgetMeanPlot(Iterable<TreeSet<Double>>).

2 番目のメソッドに渡される直前に iterable はどのように正しいのですが、2 番目のメソッドが開始されたときに例外をスローしますか?

スタックトレース

スタック トレースは、Maps.EntryTransformerオブジェクトToRescaledValueMapが原因であることを示しています。トレースは次のとおりです。

Exception in thread "main" java.util.NoSuchElementException
    at java.util.TreeMap$PrivateEntryIterator.nextEntry(TreeMap.java:1113)
    at java.util.TreeMap$EntryIterator.next(TreeMap.java:1151)
    at java.util.TreeMap$EntryIterator.next(TreeMap.java:1146)
    at com.google.common.collect.AbstractMapBasedMultimap$Itr.next(AbstractMapBasedMultimap.java:1145)
    at com.google.common.collect.Ordering.min(Ordering.java:460)
    at com.google.common.collect.Ordering.min(Ordering.java:479)
    at DistributionMetricExperiment$6.transformEntry

これは Guava の遅延初期化と何か関係がありますか? メソッドを使用する代わりに、独自の小さなメソッドを作成することもできますが、Maps#transformEntriesこのバグの背後にある理由がわからないということは...まあ...私を悩ませています。エントリの変換は次のとおりです。

static Maps.EntryTransformer<Integer, TreeMultimap<String,Double>, TreeSet<Double>>
ToRescaledValueMap(final double interval_length) {
    return new Maps.EntryTransformer<Integer, TreeMultimap<String,Double>, TreeSet<Double>>()
    {
        public TreeSet<Double> transformEntry(Integer i, TreeMultimap<String,Double> mmap) {
            double mmap_min = Ordering.natural().min(mmap.values());
            double mmap_max = Ordering.natural().max(mmap.values());
            TreeSet<Double> rescaledValues = Sets.newTreeSet();
            for (double val : mmap.values())
                rescaledValues.add(interval_length * (val - mmap_min)/(mmap_max - mmap_min));
            return rescaledValues;
        }
    };
}

編集

  • これが問題かどうかはわかりませんがIterable<TreeSet<Double>getMeanPlot. そこでも問題なく印刷され、例外がスローされます。
  • 変数名にアンダースコアを使用していることをお詫びします。変数は、コードの背後にある数学で使用している添字を反映しています。命名規則については承知していますが、このコードでは、変数を見ただけでその数学的意味を認識できるようにすることに重点を置いていました。
4

1 に答える 1

1

実際に を印刷するTreeSet<Double> setと、コレクションにデータが入力されていると誤解されます。あなたのエラーは onsetではなく on であるため、TreeMultimap<String,Double> mmap実行するOrdering.natural().min(mmap)と問題が発生します。Guava は、空のコレクションで最小 (または最大) 要素を探すと、NoSuchElementExceptionここにある がスローされることを指定しています。

于 2014-03-07T00:27:40.917 に答える