2014-01-13 3 views
3

Насколько я знаю, строковые массивы в Android не являются динамическими. По крайней мере, согласно тому, что мне сказали на этом сайте. Я не могу просто создать массив строк, а затем добавить к нему столько элементов, сколько захочу. Чтобы обойти это, вы делаете ListArray, а затем преобразовываете его в массив String, когда вы закончили массив. Если бы я был неправильно информирован об этом, то вы можете ответить на этот вопрос, сказав мне, как создать динамический массив строк, например:Android String Array Inside If Statement

String[] menuList = new String[]; 
menuList.add("One"); 
menuList.add("A"); 
String firstItem = menuList[0]; 
menuList.add("Two"); 

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

Предполагая, что это невозможно, я пытаюсь установить массив на основе данных в текстовом файле в Интернете. Пока все хорошо, и каждый раз, когда они обращаются к этому текстовому файлу, приложение сохраняет текстовый файл локально в приложении. Все еще хорош. Однако, если нет доступа в Интернет, я хочу, чтобы массив String был основан на сохраненном локальном текстовом файле. Проблема в том, что я считаю, что мне нужно объявить длину массива строк по мере его создания, и если я создам его в выражении if, остальная часть приложения не узнает его. Как это:

ListArray<String> menuList = getFile(filename); 
//The above line populates the ListArray with the online file, and returns an empty ListArray if there is no internet connection or if there is some problem with getting the file. 
//Now I want to populate a String[] with the ListArray if it was successful (and overwrite the local copy), or if it was unsuccessful, I want to get the local copy and populate it with that. 
if(menuList.size != 0){ 
    writeToFile("Menu List", menuList); 
    String[] menuArray = menuList.toArray(new String[menuList.size()]); 
} else { 
    String[] menuArray = readFromFile("Menu List"); 
} 
setUpView(menuArray); 

Теперь, очевидно, это не будет работать, потому что setUpView не может видеть, что menuArray была создана, так как он находится внутри, если заявление. Как я могу использовать массив String (вместо простого использования ListArray), используя инструкцию if для определения его содержимого?

Я должен упомянуть, так как теперь я написал проблему, я уже вижу несколько работ вокруг. Например, я могу просто комбинировать методы записи и чтения, и тогда мне не нужно будет использовать оператор if здесь. Или я мог бы просто работать с ListArray до последней минуты или установить String [] намного дольше, чем мне нужно, и перестать вытягивать его, когда он попадает в пустой слот. Тем не менее, использование String [] в инструкции if возникло раньше, и я хотел бы знать, как реализовать такую ​​вещь, если это возможно. Мысли?

+0

это не имеет ничего общего с Android, то, как массивы (не только строковые массивы) работают в Java. – njzk2

+1

По-моему, использование статической реализации массива неэффективно, потому что, когда вы изменяете его размер (arrayList), то, что на самом деле происходит, заключается в том, чтобы объединить в основной памяти в два раза больше его размера, а затем пересечь массив и обновить второй. Первый собирает мусор. В реализациях для динамических списков есть java-сборка, почему вы их не используете? – nmargaritis

+0

Почему бы вам не ограничить себя использованием только массивов? (а также вы можете заметить, что ваша проблема не связана с тем, что массивы являются неизменяемыми, поскольку у вас будет такая же проблема с любым объектом, поскольку это только вопрос объема.) – njzk2

ответ

1

Вам необходимо объявить переменную за пределами инструкции if, а затем назначить ее внутри.

String[] menuArray; 
if(menuList.size != 0){ 
    writeToFile("Menu List", menuList); 
    menuArray = menuList.toArray(new String[menuList.size()]); 
} else { 
    menuArray = readFromFile("Menu List"); 
} 
+0

Не нужно ли указывать длину объявления? Мне сказали, что мне придется это сделать раньше. –

+0

@MarcelMarino: Вы смешиваете переменные с объектами. Вы должны установить длину при создании _instance_ массива. – SLaks

1

Я не могу просто создать массив строк, а затем добавить много элементов к нему всякий раз, когда я чувствую, как она. Чтобы обойти это, вы делаете ListArray и , затем преобразовываете его в массив String, когда вы закончите массив. Если был misinformed об этом, то вы можете ответить на этот вопрос , рассказывая мне, как создать динамический массив String.

На мой взгляд, используя статическую реализацию массива не является эффективным, так как при изменении размеров его (ArrayList), что на самом деле происходит, чтобы alocate в основной памяти в два раза его размер, а затем пройти через массив и обновление второй. Первый собирает мусор. Для динамических списков предусмотрены java-реализации, почему вы их не используете?

Примеры: см LinkedList

Я не могу просто создать массив строк, а затем добавить много элементов к нему всякий раз, когда я чувствую, как она. Чтобы обойти это, вы делаете ListArray и , затем преобразовываете его в массив String, когда вы закончите массив.

Вам не нужно создавать свой собственный динамический список (поскольку существуют java-реализации), однако я собираюсь объяснить, как они работают, поэтому вы можете получить представление об этом. Динамические списки реализуются с узлом класса, который удерживает указатель на следующем узле, поэтому все вместе формируют список подключенных элементов. Более того, первый элемент списка помечается как глава списка, а последний - как хвост (если вы используете LinkedList из java, есть двойные указатели, сохраняя предыдущий и следующий узел, чтобы вы могли двигаться назад, если это необходимо). Разница между динамическим списком и массивом заключается в том, что вы не объявляете его размер, а добавляете столько элементов, сколько хотите, и выделяете только размер этих узлов в основной памяти. С другой стороны, статические массивы требуют выделения памяти для всего ее размера, хотя у вас есть пустой пробел. Кроме того, узлы хранятся не последовательно в основной памяти, что имеет место со статическими массивами, так как такая сложность времени O (1) может быть достигнута при доступе к индексу.

Пример того, как это работает:

public class Node { 
    private Object item; 
    private Node next; 

    public Node() { 
     next = null; 
    } 

    public Node(Object newItem) { 
     item = newItem; 
     next = null; 
    } 

    public Node(Object newItem, Node nextNode) { 
     item = newItem; 
     next = nextNode; 
    } 

    public void setItem(Object newItem) { 
     item = newItem; 
    } 

    public Object getItem() { 
     return item; 
    } 

    public void setNext(ListNode nextNode) { 
     next = nextNode; 
    } 

    public Node getNext() { 
     return next; 
    } 
} 
public class LinkedList { 
    private Node head; 
    private Node tail; 
    int numItems; 

    public LinkedList() { 
     head = tail = null; 
     numItems = 0; 
    } 

    public int size() { 
     return numItems; 
    } 

    public boolean isEmpty() { 
     return (numItems == 0); 
    } 

    public void removeAll() { 
     head = tail = null; 
     numItems = 0; 
    } 

    private Node find(int index) { 
     ListNode curr = head; 
     for (int skip = 1; skip < index; skip++) 
      curr = curr.getNext(); 
     return curr; 
    } 

    // Etc for the other methods.. like add/remove/etc 
} 

EDIT

Приведенный выше пример не является лучшим вариантом для использования. Я просто предоставляю это для понимания, есть и другие вещи, которые могут быть использованы , например, двоичное дерево поиска или hashMap. сложность алгоритмов сбалансированного двоичного дерева поиска представляет собой О (журнал N) в то время как HashMap имеет алгоритм сложности из O (1) до O (N) (более часто O (1))

+0

Связанный список ужасен, как только вам нужно получить доступ к любому произвольному значению. (и имеют ужасный постоянный фактор (см. http://docs.oracle.com/javase/tutorial/collections/implementations/list.html)) – njzk2

+0

@ njzk2 Я согласен. Однако они лучше, чем статическая реализация i.e ArrayList (поскольку в этом случае происходит изменение размера). Кроме того, я просто предоставляю пример, есть другие вещи, которые можно использовать, например, двоичное дерево поиска или hashMap. Сложность алгоритма сбалансированного дерева двоичного поиска - O (log n), а hashMap имеет сложность алгоритма от O (1) до O (n) (чаще O (1)). – nmargaritis

1

цитирую SLaks's answer и я хотел бы добавить ответ на ваш комментарий здесь, поскольку у меня пока нет достаточной репутации. Вам не нужно указывать длину в объявлении. Линия

String[] menuArray;

фактически только объявляет ссылку на объект массива, он не создает сам объект, он не выделяет память для массива (за исключением крошечного бита для ссылки на стеке) , Не забудьте инициализировать переменную перед ее доступом.

Это, я думаю, если вы ищете «расширяемый» массив, то вы должны использовать ArrayList и интерфейс List. Объект ArrayList, а не ListArray, представляет собой «Реализуемый вариант реализации интерфейса List» из официальных документов Java.

Не могли бы вы изменить способ setUpView взять List? Если вы не можете все еще преобразовать ArrayList в массив и обратно с:

List<String> menuList; 
// ... 
String[] arr = (String[]) menuList.toArray(); 
List<String> list = new ArrayList<String>(Arrays.asList(arr)); 
+0

Спасибо, что объяснили это. –

+0

Не беспокойтесь. Кроме того, для последней строки у вас может возникнуть соблазн написать 'Список list = Arrays.asList (arr);' , но это создаст немодифицируемый 'List'. Он будет скомпилирован, но как только вы попытаетесь добавить элемент, скажем, 'list.add (« hello »)', тогда будет выбрано исключение. Это обычная ошибка, с которой все рано или поздно сталкиваются –