7

ソートされたオブジェクトのセットが必要で、現在TreeSet. 私の問題はcompareTo、オブジェクトの がしばしば を返すことです0。つまり、これら 2 つのオブジェクトの順序は変更されないままにしておく必要があります。TreeMap(TreeSetデフォルトで使用) はそれらを同じオブジェクトと見なしますが、これは正しくありません。

どのような代替手段をTreeMap使用できますか?


ユースケース: 表示可能なオブジェクトのセットがあります。正しい順序でレンダリングされるように、Y 座標で並べ替えたいと思います。もちろん、2 つのオブジェクトの Y 座標が同じ場合もあります。

4

5 に答える 5

9

比較する基準を 1 つ定義していますが、別の基準を追加する必要があります。

あなたは言う:

表示可能なオブジェクトのセットがあります。正しい順序でレンダリングされるように、Y 座標で並べ替えたいと思います。もちろん、2 つのオブジェクトの Y 座標が同じ場合もあります。

では、2 つの要素の Y 座標が同じ場合、最初に何を配置しますか? 他の基準は何でしょうか?

作成時間かもしれませんし、x 座標かもしれません。それを定義するだけです:

Map<String,Thing> map = new TreeMap<String,Thing>(new Comparator<Thing>(){
     public int compare( Thing one, Thing two ) {
         int result = one.y - two.y;
         if( result == 0 ) { // same y coordinate use another criteria
             result = one.x - two.x;
             if( result == 0 ) { //still the same? Try another criteria ( maybe creation time
                 return one.creationTime - two.creationTime
             }
          }
          return result;
     }
});

Thingoneが他のものよりも高い/低い/等しい/いつであるかを定義する必要がありますThing。属性の 1 つが他の属性と同じである場合、おそらくそれらを移動するべきではありません。比較する他の属性がある場合は、それを使用します。

于 2010-06-14T21:16:30.643 に答える
4

あなたが直面している問題は、compareTo返さ0れることはオブジェクトが等しいことを意味するということです。同時に、同じ要素の複数のコピーを許可しないセットにそれらを入れています。

compareTo等しくない要素が異なる値を返すようにyour を書き直すかjava.util.PriorityQueue、等しい要素の複数のコピーを許可する a のようなものを使用してください。

于 2010-06-14T21:39:58.513 に答える
1

私は前にこれをやったことがあります。これは順序付けられたマルチマップであり、単なる List オブジェクトの TreeMap です。このような..

Map<KeyType, List<ValueType>> mmap = new TreeMap<KeyType, List<ValueType>>();

新しいキーが導入されるたびに、新しい LinkedList を構築する必要があるため、カスタム コンテナー クラスでラップすると役立つ場合があります。何か見つけてみます。


そのため、このカスタム コンテナーをすばやくまとめました (完全にテストしていません) が、探しているものである可能性があります。値リストの順序付きマップを本当に探している場合にのみ、このタイプのコンテナを使用する必要があることに注意してください。値に自然な順序がある場合は、他の人が提案したように TreeSet を使用する必要があります。

import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class MTreeMap<K, V> {

   private final Map<K, List<V>> mmap = new TreeMap<K, List<V>>();
   private int size = 0;

   public MTreeMap() {
   }

   public void clear() {
      mmap.clear();
      size=0;
   }

   public boolean containsKey(K key) {
      return mmap.containsKey(key);
   }

   public List<V> get(K key) {
      return mmap.get(key);
   }

   public boolean isEmpty() {
      return mmap.isEmpty();
   }

   public Set<K> keySet() {
      return mmap.keySet();
   }

   public Collection<List<V>> valueLists() {
      return mmap.values();
   }

   public void put(K key, V value) {

      List<V> vlist = mmap.get(key);
      if (null==vlist) {
         vlist = new LinkedList<V>();
         mmap.put(key, vlist);
      }
      vlist.add(value);
      ++size;
   }

   public List<V> remove(Object key) {
      List<V> vlist = mmap.remove(key);

      if (null!=vlist) { 
         size = size - vlist.size() ;
      }
      return vlist;
   }

   public int size() {
      return size;
   }

   public String toString() {
      return mmap.toString();
   }

}

初歩的なテストは次のとおりです。

public class TestAnything {

   public static void main(String[] args) {

      MTreeMap<Integer, String> mmap  = new MTreeMap<Integer, String>();

      mmap.put(1, "Value1");
      mmap.put(2, "Value2");
      mmap.put(3, "Value3");
      mmap.put(1, "Value4");
      mmap.put(3, "Value5");
      mmap.put(2, "Value6");
      mmap.put(2, "Value7");

      System.out.println("size (1) = " + mmap.get(1).size());
      System.out.println("size (2) = " + mmap.get(2).size());
      System.out.println("size (3) = " + mmap.get(3).size());
      System.out.println("Total size = " + mmap.size());

      System.out.println(mmap);
   }

}

出力は次のとおりです。

size (1) = 2
size (2) = 3
size (3) = 2
Total size = 7
{1=[Value1, Value4], 2=[Value2, Value6, Value7], 3=[Value3, Value5]}
于 2010-06-14T21:44:48.250 に答える
0

私は自分のアイデアを1つ持っていますが、それは回避策です

int compare(Object a, Object b) {
   an = a.seq + (a.sortkey << 16); // allowing for 65k items in the set
   bn = b.seq + (a.sortKey << 16);
   return an - bn; // can never remember whether it's supposed to be this or b - a.
}
  • sortKey = Y 座標など、ソートに本当に重要なもの
  • seq = セットに追加されたときにオブジェクトに割り当てられるシーケンス番号
于 2010-06-14T20:52:32.213 に答える
0

ソート済みセット (例: TreeSet) を使用する際に覚えておくべき重要な点が 2 つあります。

1) それらはセットです。同じコレクション内で 2 つの等しい要素は許可されません

2) 平等性は、比較メカニズム (比較対象または比較可能) と一致している必要があります。

したがって、あなたの場合、いくつかの二次的な順序付け基準を追加して「関係を断ち切る」必要があります。例: 最初に Y 軸を使用し、次に X 軸を使用し、次に一意のオブジェクト識別子を使用します。

http://eyalsch.wordpress.com/2009/11/23/comparators/も参照してください。

于 2010-06-14T21:25:53.620 に答える