Как получить подсписок без использования метода подсписка в java

Это то, что у меня есть прямо сейчас:

public ArrayList subList(int fromIndex, int toIndex){
      ArrayList a = new ArrayList();
      for (int i=fromIndex;i<toIndex;i++) {
          a.add(stuff[i]); //stuff is a array of strings
      }
    return list;
  }

Но можно ли вернуть подсписок без создания нового массива? Я не могу использовать любые методы из класса Array/ArrayList.


person Dan    schedule 05.10.2010    source источник
comment
Значит, ваша задача — реализовать subList самостоятельно? Также непонятно, для чего нужен массив stuff.   -  person Brad Mace    schedule 05.10.2010
comment
Да, это правильно. stuff — это массив строк, на которых я его тестирую.   -  person Dan    schedule 05.10.2010
comment
и какой метод должен вернуть?   -  person user85421    schedule 05.10.2010
comment
кто-нибудь знает, как добавить объект из одного массива в другой без использования метода добавления?   -  person Dan    schedule 08.10.2010


Ответы (5)


Если вы хотите иметь то же поведение, что и метод подсписка Java, вам нужно сохранить указатель на исходный список и использовать смещение и длину для индексации исходного списка.

Вот начало, показывающее реализацию метода get.

public class SubList extends AbstractList {
    private final List original;
    private final int from;
    private final int to;
    public SubList(List original, int from, int to) {
        this.original = original;
        this.from = from;
        this.to = to;
    }

    public Object get(int i) {
        if (i < 0 || i > to - from) {
            throw new IllegalArguementException();
        }

        return original.get(from + i);
    }
}

public static List subList(List original, int from, int to) {
    return new SubList(original, from, to);
}
person Michael Barker    schedule 05.10.2010
comment
Ааа, думаю, это то, что искал ОП. Хороший. Вы обертываете List, но если вы хотите обернуть массив, решение аналогичное. - person Andreas Dolk; 05.10.2010
comment
+1. для полного поведения подсписка Java вам также необходимо поддерживать удаление и очистку и т.д. - person Thilo; 05.10.2010
comment
есть ли способ реализовать без таких методов, как добавить, удалить, получить, содержать, установить и т. д.? - person Dan; 05.10.2010
comment
@Dan - методы должны быть реализованы, но вам, возможно, не придется кодировать реализацию самостоятельно. Подсказка: какой класс расширяет ArrayList? - person Stephen C; 05.10.2010
comment
@Thilo - ... что, очевидно, невозможно, если ваш список оборачивает массив. Единственный выход: объявить пользовательский список немодифицируемым и генерировать исключения для всех методов, которые могут изменить список, например add, remove, clear,... - person Andreas Dolk; 05.10.2010

Чтобы избежать создания нового списка для хранения, вам нужно будет передать ссылку на исходный список, сохранить подсписок, а затем удалить оставшиеся элементы из списка, но это оставит список без этих других элементов.

Если это не ваша цель, вам придется в какой-то момент создать новый список, чтобы сохранить подсписок.

person Jan Oglesby    schedule 05.10.2010
comment
Выше отмечалось, что «материал» — это массив, а не список. - person Moncader; 05.10.2010
comment
Я тоже об этом думал, но я не могу использовать ни один из методов класса Array, поэтому нет возможности удалить - person Dan; 05.10.2010

Я предполагаю, что вам нужно вернуть стандартный ArrayList, а не вашу собственную версию ArrayList, и я предполагаю, что «материал» — это массив, а не список.

Во-первых, получите бонусные баллы за то, что ArrayList имеет начальный размер массива (toIndex - fromIndex). Чтобы получить дополнительные бонусные очки, убедитесь, что в «вещах» действительно существуют непристойности «туда-обратно», иначе вы получите хороший сбой.

ArrayList использует внутренний массив для хранения, и вы не можете его изменить, поэтому у вас нет другого выбора, кроме как создать копию.

РЕДАКТИРОВАНИЕ Вы можете сделать вещи более интересными и сложными, но это кого-то впечатлит... Сделайте это, создав свой собственный класс ArrayList, реализующий List. Заставьте его использовать этот исходный массив. Довольно нестабилен, поскольку, если этот массив будет изменен где-то еще извне, у вас будут проблемы, но это может быть весело.

person Moncader    schedule 05.10.2010

Есть три разумные вещи, которые вы могли бы вернуть. Массив, список или итератор. Если мое предположение о том, что вы должны повторно реализовать subList, было верным, то нет способа создать новый ArrayList.

person Brad Mace    schedule 05.10.2010

Подсписок — это «новый список», поэтому вам нужно будет создать нечто, представляющее подсписок массива. Это может быть либо новый массив, либо список. Вы выбрали ArrayList, который мне нравится. Вы не создаете новый массив (напрямую), поэтому я не понимаю этого вопроса. (Если вы хотите избежать создания нового массива косвенно через ArrayList, выберите другую List реализацию, например LinkedList)

Если вы ищете небольшие улучшения:

  • Рассмотрите возможность передачи исходного массива в качестве параметра метода. Теперь stuff[] является статическим полем.
  • Рассмотрите возможность инициализации нового ArrayList с размером подсписка (toList-fromList+1)
  • Подумайте об использовании дженериков (только если вы уже знакомы с этой концепцией). Таким образом, возвращаемый тип будет ArrayList<String>
person Andreas Dolk    schedule 05.10.2010