2017-08-09 16 views
1

キーではなく値に基づいて比較を行うカスタムコンパレータを使用してNavigableMapを実装しようとしています。私は非常に非常にJavaとコーディング一般的に私の用語がinccorectまたはコード恐ろしい場合は私を許して知っている!私は解決策を試してみて、複製するために同様の質問を見つける試みたが、私がコンパイルしようとすると、まだ次のエラーが供給しています:NavigableMap - 値に基づいて比較

java: no suitable constructor found for TreeMap(OrderLineSegments) 
    constructor java.util.TreeMap.TreeMap(java.util.Comparator<? super java.lang.Float>) is not applicable 
     (argument mismatch; OrderLineSegments cannot be converted to java.util.Comparator<? super java.lang.Float>) 
    constructor java.util.TreeMap.TreeMap(java.util.Map<? extends java.lang.Float,? extends java.lang.Float[]>) is not applicable 
     (argument mismatch; OrderLineSegments cannot be converted to java.util.Map<? extends java.lang.Float,? extends java.lang.Float[]>) 
    constructor java.util.TreeMap.TreeMap(java.util.SortedMap<java.lang.Float,? extends java.lang.Float[]>) is not applicable 
     (argument mismatch; OrderLineSegments cannot be converted to java.util.SortedMap<java.lang.Float,? extends java.lang.Float[]>) 

フロートは[] 4つのfloatの配列です、私は次のことを実現しようとしています[ x1、y1、x2、y2]は線分を表す。

NavigableMap<Float, Float[]> segmentBST = new TreeMap<Float, Float[]>(new OrderLineSegments()); 

class OrderLineSegments implements Comparator<Map.Entry<Float, Float[]>> { 
public int compare(Map.Entry<Float, Float[]> a, Map.Entry<Float, Float[]> b) { 
    float ypos; 
    if (a.getValue()[1] < a.getValue()[1]) { 
     ypos = a.getValue()[1]; 
    } else { 
     ypos = b.getValue()[1]; 
    } 
    float ratioA = (a.getValue()[1] - ypos)/(ypos - a.getValue()[3]); 
    float ratioB = (b.getValue()[1] - ypos)/(ypos - b.getValue()[3]); 
    float posA = Math.abs(a.getValue()[0] - a.getValue()[2]) * ratioA + a.getValue()[0]; 
    float posB = Math.abs(b.getValue()[0] - b.getValue()[2]) * ratioB + b.getValue()[0]; 
    if (posA < posB) return 1; 
    if (posA > posB) return -1; 
    return 0; 
} 

私は、これは、これを行うための最善の方法であるか、これがも可能ですので、もしどのような援助が大幅に高く評価されている場合でも、わかりません。

+0

'Comparator'は*キー*を比較するために使われるので、' OrderLineSegments'は 'Comparator 'を実装する必要があります。したがって、 'Map.Entry'を比較しようとしているときのエラーです。 – Kayaman

+0

docが言うように、エラーは正常であるようです: 'TreeMapのコンストラクタはコンパレータ'を必要とし、 'Comparator 'を提供します。キーと値を逆にすることはできません。同じ値を持たない場合は、変更することがあります – azro

+0

あなたはNavigableMapの契約を破棄しています。この場合、ソートされたリストを使用するだけではどうですか? – daniu

答えて

0

コンパレータをサポートマップを持つ別個のオブジェクトとして作成し、比較メソッドでこの同じマップから値を取得することができます。この後、あなたのロジックを値に適用することができます。 また、実際のナビゲート可能なマップに入れる前に、コンテンツをサポートマップに置くオーバーライドされた「put」メソッドを使用して、ツリーマップの拡張を使用する必要があります。これらの線に沿って

何か:

public static void main(String[] args) throws IOException { 
    // Sun, 27 Jul 2014 10:19:10 +0100 

    class OrderLineSegments implements Comparator<Float> { 

     private Map<Float, Float[]> supportMap = new HashMap<>(); 

     public int compare(Float aKey, Float bKey) { 
      Float[] aValue = supportMap.get(aKey); 
      Float[] bValue = supportMap.get(bKey); 
      float ypos; 
      if (aValue[1] < bValue[1]) { 
       ypos = aValue[1]; 
      } else { 
       ypos = bValue[1]; 
      } 
      float ratioA = (aValue[1] - ypos)/(ypos - aValue[3]); 
      float ratioB = (bValue[1] - ypos)/(ypos - bValue[3]); 
      float posA = Math.abs(aValue[0] - aValue[2]) * ratioA + aValue[0]; 
      float posB = Math.abs(bValue[0] - bValue[2]) * ratioB + bValue[0]; 
      if (posA < posB) return 1; 
      if (posA > posB) return -1; 
      return 0; 
     } 

    } 

    OrderLineSegments orderLineSegments = new OrderLineSegments(); 

    class ExtendendNavigableMap extends TreeMap<Float, Float[]> { 

     private OrderLineSegments orderLineSegments; 

     public ExtendendNavigableMap(OrderLineSegments comparator) { 
      super(comparator); 
      orderLineSegments = comparator; 
     } 

     @Override 
     public Float[] put(Float key, Float[] value) { 
      orderLineSegments.supportMap.put(key, value); 
      return super.put(key, value); 
     } 
    } 

    NavigableMap<Float, Float[]> segmentBST = new ExtendendNavigableMap(orderLineSegments); 

    // Start adding elements 
    segmentBST.put(1.0F, new Float[]{0.1f, 0.2f, 0.3f, 0.4f}); 
    segmentBST.put(1.9F, new Float[]{0.3f, 0.2f, 0.3f, 0.4f}); 
    segmentBST.put(1.1F, new Float[]{-0.3f, 0.2f, 0.3f, 0.4f}); 

    segmentBST.forEach((k, v) -> System.out.printf("%s:%s%n", k, Arrays.toString(v))); 
} 

が出力:

1.9:[0.3, 0.2, 0.3, 0.4] 
1.0:[0.1, 0.2, 0.3, 0.4] 
1.1:[-0.3, 0.2, 0.3, 0.4] 

このソリューションは複雑かつ醜いですが、それは間違いなく動作するはずです。キーと値の両方を含むオブジェクトを持つツリーセットを使用して、あなたの質問に示唆された実装ロジックでカスタムコンパレータを作成する方が自然です。

+0

ありがとう!これは現在コンパイル中です。 マップの順序は、compare関数に従っていないようですが。例えば : マップがすでに含まれている場合:1.3283を:[1.3283、89.719、5.7766、70.22] と私が追加:3.2011:[3.2011、72.564、14.316、55.937] それは(左に挿入する必要がありますすなわち、下位の位置)にあり、次のようになります。 {3.2011:[3.2011,72.564,14.316,55.937]、1.3283:[1.3283,89.719,5.766,70.22] 比較が呼び出されていないように見えます。これは、次のとおりです: {1.3283:1.3283,89.719,5.7766,70.22,3.2011:[3.2011,72.564,14.316,55.937]} – fortymod

+0

私は比較ブロック内にprintlnステートメントを配置し、何も印刷されませんでした。私はこれが使用されていないことと、自然なキー順序が使用されていることを示していると仮定します。これを実装するために何か他に必要なことはありますか? – fortymod

+0

私の謝罪、これは確かに事実です。私は答えを更新しました。もう一度コードを試してみてください。それがあなたのために働いた場合は、私に知らせてください。 –

関連する問題