Объедините два списка в постоянное время в Java

Кто-либо знает, возможно ли объединить два списка (или какой-либо набор) в постоянное время в Java?

http://www.cppreference.com/wiki/stl/list/splice

Настолько легко сделать то использование связанные списки в C...

Спасибо,

12
задан Damien 10 February 2010 в 14:05
поделиться

3 ответа

Насколько мне известно, классы в библиотеке JDK не поддерживают это.

Это возможно, если вы создадите свою собственную реализацию List - что вы можете делать свободно, это совершенно законно. Вы можете использовать LinkedList и признать особый случай, когда добавляемая коллекция также является LinkedList .

При документировании вашего класса вам нужно указать, что добавленный объект становится частью нового объекта, другими словами, теряется много общности. Также есть много возможностей для ошибки: изменение любого из исходных списков (если они изменяемые) после присоединения позволит вам создать список с пробелом в нем или с двумя хвостами. Кроме того, ваш взломанный класс не принесет пользы большинству других операций. Другими словами, на первый взгляд это кажется безумной идеей.

Обратите внимание, что «объединение» списков обычно имеет разные коннотации; при объединении отсортированных списков, например, можно было бы ожидать, что результирующий список будет иметь такой же порядок. То, о чем вы говорите о соединении двух связанных списков, на самом деле лучше назвать «сращиванием». Или, может быть, просто «присоединиться».

11
ответ дан 2 December 2019 в 20:40
поделиться

Вы можете реализовать составную «оболочку» вокруг нескольких Список с. Для простоты я сделал свой пример неизменяемым, но вы всегда можете реализовать add для добавления к «окончательному» списку , хранящемуся в составном объекте.

public class CompositeImmutableList<T> implements List<T> {
  private final List<T> l1;
  private final List<T> l2;

  public CompositeImmutableList(List<T> l1, List<T> l2) {
    this.l1 = l1;
    this.l2 = l2;
  }

  public boolean add(T t) {
    throw new UnsupportedOperationException();
  }

  public int size() {
    return l1.size() + l2.size();
  }

  public T get(int i) {
    int sz1 = l1.size();
    return i < s1 : l1.get(i) : l2.get(sz1 - i);
  }

  // TODO: Implement remaining List API methods.
}
3
ответ дан 2 December 2019 в 20:40
поделиться

Если это легко сделать со связным списком в C, то я бы предположил, что класс LinkedList предлагает такую же производительность

Все операции выполняются так, как можно было бы ожидать для дважды связного списка. Операции, индексирующие список, обходят список с начала или конца, в зависимости от того, что ближе к указанному индексу.

List list1 = new LinkedList();
list1.add(...);
List list2 = new LinkedList();
list2.add(...);

list1.addAll(list2);

edit: Nevermind. Похоже, что LinkedList.addAll(Collection) вызывает LinkedList.addAll(int, Collection), который выполняет итерации по новой коллекции.

0
ответ дан 2 December 2019 в 20:40
поделиться
Другие вопросы по тегам:

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