Вопрос по java – Изменение порядка коллекции в соответствии со списком идентификаторов

1

У меня есть коллекция (неупорядоченные) объектов сid собственности и (упорядоченный) списокids. The id list is not sorted, Я хотел бы создать список объектов в моей коллекции, упорядоченный в соответствии со списком идентификаторов.

Я не видел метод для этого в Guava или Apache Commons - но это именно то, что я искал. Функция библиотеки с хорошей реализацией.

Ваш Ответ

6   ответов
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) ты можешь уйти от п ^ 2

0

Создайте класс, который реализует Comparable. В этом классе выполните сортировку в соответствии с вашим упорядоченным списком идентификаторов. Затем определите TreeSet на основе класса Comparable. Очень упрощенный пример показан ниже.

например

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, то & quot; 17 & quot; вступление будет происходить до "12" запись.

3

Похоже, ваш список идентификаторов имеет свой собственный порядок; Вы не просто используете естественный порядок, верно?

Вот решение Guava:

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

Вот и все. Ничего подобного. (Раскрытие: я помогаю гуаве.)

С другой стороны, если вы знаете, что идентификаторы являются уникальными, это может просто сказать

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));
Это интересно, и в значительной степени то, что я ожидал. Eyal
Кроме того, если вы хотите отсортировать список ввода на месте, просто используйтеCollections.sort(list, Ordering.explicit(idList).onResultOf(..)), так какOrdering такжеComparator.
0

Вы можете:

В первом решении вам нужно изменить свой объект, а во втором - создать другой класс, но вы можете оставить свой объект без изменений. <T> ваш класс объектов

0

Прочитайте список идентификаторов, скопировав коллекцию в новый список в порядке списка идентификаторов.

1

Если ваш неупорядоченный ввод не более специфичен, чем Collection, и ваш Список идентификаторов находится в произвольном порядке (не уменьшаясь численно или что-то в этом роде), ваш простейший и довольно производительный подход, вероятно, такой. Стоимость является линейной, O (m + n), где m - количество идентификаторов в первоначально отсортированном списке, а 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);
    }
}
Похоже, решение Guava тоже это сделает. Если производительность не критична, я бы выбрал то, что вы считаете наиболее читабельным.
Это была моя первая мысль, если бы я не нашел чего-то более чистого, уже написанного в библиотеке. Возможно, это будет либо то, что предложил @Louis. Eyal

Похожие вопросы