根据ID的相关列表的重新集合(Reordering a collection according t

2019-06-24 23:02发布

我有一个id属性对象的集合(无序),和IDS的(有序)列表。 未排序的ID列表 。 我想创造我的收藏对象的列表,根据ID列表排序。

我没有看到番石榴或Apache共享这个方法 - 但是这正是我要找的。 库函数具有良好的实施。

Answer 1:

这听起来像你的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

而已。 没有什么不可以。 (披露:我贡献番石榴)。

或者,如果你知道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));


Answer 2:

如果你的无序输入不超过集合更具体和你的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);
    }
}


Answer 3:

听起来像是你有你想要一个给定的顺序,可能会或可能不会进行数值上升/下降?

我会建议做下面你自己的谓语。 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



Answer 4:

阅读ID的列表中,复制收集到的ID列表顺序一个新的列表。



Answer 5:

创建一个实现Comparable的类。 在这个类,根据你的命令ID列表进行排序。 然后定义基于可比类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”项之前。



Answer 6:

您可以:

  • 实现该接口可比你的对象,然后调用Collections.sort(名单)
  • 实现接口比较有一个新的类,然后调用Collections.sort(名单时,比较器)

随着第一个解决方案,你必须修改你的对象,你必须创建另一个类的第二人,但你可以留下你的对象不变。 <T>是您的对象类。



文章来源: Reordering a collection according to a related list of ids