Android: SQLite сохраняет массив строк?

Мне нужно сохранить массив строк в базу данных, но он мне не позволяет. Вот что у меня есть:

 public long createEntry(String startTime, String endTime, String[] states) {
         ContentValues initialValues = new ContentValues();
         initialValues.put(START_KEY_TIME , startTime);
         initialValues.put(END_KEY_TIME , endTime);
         initialValues.put(KEY_STATE, states );

         return databaseConnect.insert(DATABASE_TABLE, null, initialValues);
}

Но если я ввожу состояния string[], это говорит о том, что значения содержимого не могут принимать аргумент. Как мне это обойти? Я думал, что у меня есть 7 вещей в состояниях, могу ли я иметь 7 отдельных строк и хранить вещи в каждой, а затем возвращать все строки в массив строк? Или это будет плохой практикой?


person user1175899    schedule 29.01.2012    source источник
comment
Зачем нужно сохранять массив в базе данных? должно быть какое-то другое хорошее решение.   -  person Yaqub Ahmad    schedule 29.01.2012
comment
у меня есть 7 дней в неделю, но он принимает его как логическое значение (истина или ложь), и оно ДОЛЖНО быть логическим, и, поскольку вы не можете сохранить логическое значение в базе данных, я собирался использовать строковый массив, но он не позволит мне из-за значений котента любые идеи о том, что я могу сделать?   -  person user1175899    schedule 29.01.2012
comment
Вы можете хранить логические значения как целые числа 0 (ложь) и 1 (истина).   -  person Yaqub Ahmad    schedule 29.01.2012
comment
Вы можете использовать целочисленное значение для хранения значений флага. Например. для воскресенья и вторника значение будет 01010000 (двоичное) или что-то в этом роде. С учетом сказанного вам действительно следует хранить семь логических значений в отдельных столбцах.   -  person dmon    schedule 29.01.2012
comment
Другой подход может заключаться в использовании JSONObject, как описано [здесь] (stackoverflow .com/questions/5703330/)   -  person Dexter    schedule 02.03.2014


Ответы (5)


Вы не можете сохранить массив строк в базу данных. Но вы можете использовать этот прием.

1) Поэтому вам нужно преобразовать его в простую строку, используя метод convertArrayToString(String[] array). Это объединит все элементы строки с помощью «запятой».

2) Когда вы хотите получить эту строку обратно из базы данных, вы можете преобразовать ее обратно в массив строк, используя метод convertStringToArray(String str). Этот метод отделит строку от «запятой», и вы вернете исходный массив.

public static String strSeparator = "__,__";
public static String convertArrayToString(String[] array){
    String str = "";
    for (int i = 0;i<array.length; i++) {
        str = str+array[i];
        // Do not append comma at the end of last element
        if(i<array.length-1){
            str = str+strSeparator;
        }
    }
    return str;
}
public static String[] convertStringToArray(String str){
    String[] arr = str.split(strSeparator);
    return arr;
}
person Muhammad Nabeel Arif    schedule 29.01.2012
comment
Это то же самое. Когда вы объедините String с логическим значением. Boolean автоматически преобразуется в String. Когда вы вернете массив логических значений, вы должны ввести каждый элемент в логическое значение с помощью Boolean.parseBoolean(str[i]). - person Muhammad Nabeel Arif; 29.01.2012
comment
@MuhammadNabeelArif эй, я получаю проверенное значение флажка в массиве. Теперь я хочу сохранить его в базе данных, но в другой строке. Итак, как это возможно? например: [1,2,4] это мой массив, и я хочу сохранить его, например: 1, затем новую строку и сохранить 2, затем новую строку и 4. как это возможно? я новичок в Android, так что помогите - person Google; 01.01.2013
comment
Это просто, считайте каждую запись 1,2,4 и т. д. отдельной записью, теперь подготовьте строку для каждой из них и вставьте ее в БД. Вы должны понимать основы БД. Вот краткое руководство ' androidhive.info/2011/11/android -sqlite-database-tutorial ' - person Muhammad Nabeel Arif; 01.01.2013
comment
Технически я думаю, что лучше использовать StringBuilder для построения строки чисел, хотя, возможно, компилятор все равно ее оптимизирует. - person Tom; 13.09.2013
comment
это не сработает, если любой из элементов массива содержит ',' - person pellucide; 24.11.2013

На основе ответа Мухаммеда, но обрабатывает List из Strings вместо массива и использует StringBuilder вместо выделения многих Strings во время конкатенации значений:

private static final String LIST_SEPARATOR = "__,__";

public static String convertListToString(List<String> stringList) {
    StringBuilder stringBuilder = new StringBuffer();
    for (String str : stringList) {
        stringBuilder.append(str).append(LIST_SEPARATOR);
    }

    // Remove last separator
    stringBuilder.setLength(stringBuilder.length() - LIST_SEPARATOR.length());

    return stringBuilder.toString();
}

public static List<String> convertStringToList(String str) {
    return Arrays.asList(str.split(LIST_SEPARATOR));
}
person Nati Dykstein    schedule 22.06.2015

Преобразуйте его в одну строку, чтобы сохранить в sqlite. Позже извлеките его обратно из sqlite в виде одной строки и преобразуйте обратно в массив строк.

String ARRAY_DIVIDER = "#a1r2ra5yd2iv1i9der";

public String serialize(String content[]){      
    return TextUtils.join(ARRAY_DIVIDER, content);
}

public String[] derialize(String content){
    return content.split(ARRAY_DIVIDER);
}
person Aung Thiha    schedule 12.10.2014
comment
Может быть уже поздно, но... Я не могу придумать недостатка в этом ленивом методе. - person Lobstw; 03.07.2016
comment
@Lobstw это может привести к неожиданному поведению, если один из элементов content[] окажется "#a1r2ra5yd2iv1i9der". Это будет сериализовано, но при десериализации двусмысленность приведет к двум пустым строковым элементам вместо одного ошибочного строкового элемента. Если другие области программы имеют строгие требования к размеру массива, это может привести к нежелательному поведению. - person snapfractalpop; 14.05.2017
comment
@snapfractalpop да, это правильно, но если сделать разделитель длинной буквенно-цифровой строкой, это позволит избежать такого поведения примерно в 100% случаев. - person Lobstw; 15.05.2017
comment
@Lobstw в большинстве случаев согласен. Я отмечаю, что контекст для этих 0,001% случаев может быть важен. Например, если это приводит к какой-то ошибке, которая затем приводит к какому-то эксплойту безопасности в других областях кода, которые полагаются на ошибочные гарантии, 0,001% может быстро увеличиться, чтобы включить детей-скриптов и тому подобное. - person snapfractalpop; 15.05.2017

Было бы проще, если бы вы преобразовали массив строк в JSONArray, использовали toString, а затем извлекли его, сначала проанализировав в JSONArray, а затем преобразовав его в массив строк.

person jiahao    schedule 29.08.2015
comment
Это лучший метод, чем принятый ответ, потому что вас никогда не укусит строка разделителя (например, __,__ или #a1r2ra5yd2iv1i9der и т. д.), найденная в одном из элементов массива. - person Alexander Farber; 04.09.2017

Похоже, ваша база данных спроектирована не так, как должна быть. Если вы хотите сохранить логические данные в базе данных SQLite, вы можете сохранить логические значения как целые числа 0 (ложь) и 1 (истина)

person Yaqub Ahmad    schedule 29.01.2012
comment
yai может хранить как 0, 1, но, поскольку их больше одного, я должен использовать массив int, а значения содержимого не позволяют этого в любом случае? чем создавать новый int для каждого - person user1175899; 29.01.2012