1

idプロパティを持つオブジェクトの Collection (順序付けされていない) と、 idsの (順序付けられた) List があります。ID リストはソートされていません。ID のリストに従って並べ替えられた、コレクション内のオブジェクトのリストを作成したいと思います。

Guava や Apache Commons にはこの方法はありませんでしたが、まさに私が探しているものです。優れた実装を備えたライブラリ関数。

4

6 に答える 6

3

id リストには独自の順序があるようです。あなたは自然秩序を使っているだけではありませんよね?

グアバのソリューションは次のとおりです。

Ordering.explicit(idList)
     // constructs a "fluent Comparator" that compares elements in the
     // explicitly specified order
  .onResultOf(new Function<MyObject, Id>() {
    public Id apply(MyObject o) { return o.getId(); }
   }) // make this a Comparator<MyObject> that compares on IDs
  .sortedCopy(myObjects); // get the sorted copy of the collection

それでおしまい。それには何もありません。(開示:私はGuavaに貢献しています。)

あるいは、ID が一意であることがわかっている場合は、単に次のように言うかもしれません

Map<Id, MyObject> objectsById =
  Maps.uniqueIndex(myObjects, GET_ID_FUNCTION); // defined elsewhere
List<MyObject> sortedObjects = Lists.newArrayList();
for (Id id : sortedIds) 
  sortedObjects.add(objectsById.get(id));
于 2012-05-29T17:15:17.733 に答える
1

順序付けされていない入力が Collection よりも具体的ではなく、ID のリストが任意の順序 (数値の減少などではない) である場合、最も単純で非常にパフォーマンスの高いアプローチはおそらくこれです。コストは線形で、O(m+n) です。ここで、m は最初に並べ替えられたリスト内の ID の数であり、n は並べ替える値の数です。

Map<IDType, ValueType> keyed = new HashMap<IDType, ValueType>();
for (ValueType value : unsortedCollection) {
    keyed.put(value.getId(), value);
}

List<ValueType> sorted = new ArrayList<ValueType>();
for (IDType id : sortedIds) {
    ValueType value = keyed.get(id);
    if (value != null) {
        sorted.add(value);
    }
}
于 2012-05-30T01:59:37.527 に答える
0

あなたはできる:

最初の解決策ではオブジェクトを変更する必要があり、2 つ目の解決策では別のクラスを作成する必要がありますが、オブジェクトを変更しないままにしておくことができます。 <T>あなたのオブジェクトクラスです。

于 2012-05-29T15:53:16.950 に答える
0

数値的に昇順/降順である場合とそうでない場合があります。

以下で独自の述語を作成することをお勧めします。 org.apache.commons.collections.CollectionUtils.find(java.util.Collection collection, 述語 predicate);

順序付けられていないリスト内の実際の各オブジェクトを見つける特定の順序付けをループします。N^2 ソリューション

java.util.collections.sort(List list, Comparator c)およびorg.apache.find()の創造的な使用により、 java.util.collections.swap(List list, int i, int j)n^2 から逃れることができます。

于 2012-05-29T15:47:35.567 に答える
0

ID のリストを読み取り、コレクションを ID リストの順序で新しいリストにコピーします。

于 2012-05-29T15:48:18.397 に答える
0

Comparable を実装するクラスを作成します。そのクラスで、順序付けられた ID のリストに従って並べ替えを行います。次に、Comparable クラスに基づいて TreeSet を定義します。大幅に簡略化した例を以下に示します。

例えば

public class MyObject implements Comparable<MyObject> {
  private Integer id;

  // a map of IDs to how they are ordered.
  private static Map<Integer, Integer> idOrder = null;

  public MyObject(Integer id) {
      setId(id);

      if (idOrder == null) {
           idOrder = new HashMap<Integer, Integer>();
           idOrder.put(17, 1);
           idOrder.put(27, 2);
           idOrder.put(12, 3);
           idOrder.put(14, 4);
      }
  }

  public int getId() {
      return (this.id);
  }

  public void setId(int id) {
      this.id = id;
  }

  public int compareTo(MyObject anotherThing) {
    return (idOrder.get(this.getId()).compareTo(idOrder.get(anotherThing.getId()))); 
  }
}

次に、次のようにセットを定義して入力します。

private Set<MyObject> mySet = new TreeSet<MyObject>;
mySet.add(new MyObject(12));
mySet.add(new MyObject(17));

mySet.add() を実行すると、MySort クラスに従って自動的にソートされます。結果の TreeSet を反復すると、「17」エントリが「12」エントリの前になります。

于 2012-05-29T15:51:38.160 に答える