Как я могу записать SQLite Real vals в значения Java BigDecimal?

У меня есть такой класс:

public class DeliveryItem {
    private int _id;
    private String _invoiceNumber;
    private String _UPC_PLU;
    private String _vendorItemId;
    private int _packSize;
    private String _description;
    private BigDecimal _cost;
    private BigDecimal _margin;
    private BigDecimal _listPrice;
    private int _departmentNumber;
    private String _subdepartment;
    private String _quantity;

    public void setID(int id) {
        this._id = id;
    }

    public int getID() {
        return this._id;
    }
    . . .

Столбцы стоимости, маржи и списка цен имеют значение «BigDecimal», потому что в исходном (C#) приложении они были десятичными

Соответствующая таблица SQLite определяется следующим образом:

String CREATE_DELIVERYITEMS_TABLE = "CREATE TABLE " +
        TABLE_DELIVERYITEMS + "("
        + COLUMN_ID + " INTEGER PRIMARY KEY," + COLUMN_INVOICENUM + " TEXT,"
        + COLUMN_UPCPLU + " TEXT," + COLUMN_VENDORITEMID + " TEXT,"
        + COLUMN_PACKSIZE + " INTEGER," + COLUMN_DESCRIPTION + " TEXT," + COLUMN_COST +  
        " REAL,"
        + COLUMN_MARGIN + " REAL," + COLUMN_LISTPRICE + " REAL," + COLUMN_DEPTNUM + " 
        INTEGER,"
        + COLUMN_SUBDEPT + " TEXT," + COLUMN_QTY + " TEXT"
        + ")";

Ближайший SQLite подходит к Decimal (C#) или BigDecimal (Java) REAL, единственный тип данных SQLite с плавающей запятой.

В классе, который расширяет SQLiteOpenHelper, я пытаюсь выбрать значения из таблицы и сохранить их в ArrayList моего пользовательского типа класса, например:

public ArrayList<DeliveryItem> getAllDeliveryItems() {
    ArrayList<DeliveryItem>  delItems = new ArrayList<DeliveryItem>();
    String query = "Select * FROM " + TABLE_DELIVERYITEMS;

    SQLiteDatabase db = this.getWritableDatabase();

    Cursor cursor = db != null ? db.rawQuery(query, null) : null;

    if (cursor != null) {
        while (cursor.moveToNext()) {
            DeliveryItem d = new DeliveryItem();
            d.setID(Integer.parseInt(cursor.getString(0)));
            . . .
            d.set_cost(BigDecimal.valueOf(cursor.getString(6)));
            d.set_margin(BigDecimal.valueOf(cursor.getString(7)));
            d.set_listPrice(BigDecimal.valueOf(cursor.getString(8)));
            . . .
            delItems.add(d);
        }
    }
    if (cursor != null) {
        cursor.close();
    }

    return delItems;
}

Обратите внимание, что я могу назначить строковые значения классу DeliveryItem, используя "cursor.getString(N)", и целочисленные значения, используя "Integer.parseInt(cursor .getString(0))", но что касается значений BigDecimal, у меня возникла проблема.

Тип/класс данных BigDecimal в Java не имеет связанного с ним метода parseBigDecimal.

Если я попробую это:

d.set_cost(BigDecimal.valueOf(cursor.getString(6)));

Я получаю: "ошибка: не найден подходящий метод для метода valueOf(String) BigDecimal.valueOf(long) неприменим (несоответствие аргументов; строка не может быть преобразована в long) метод BigDecimal.valueOf(double) неприменим ( несоответствие аргумента; строка не может быть преобразована в двойную)"

... и если я попробую это:

d.set_cost(Float.parseFloat(cursor.getString(6)));

... я получаю "ошибка: несовместимые типы: число с плавающей запятой не может быть преобразовано в BigDecimal"

Если я попробую Double.parseDouble(), я получу нечто похожее: "...double не может быть преобразовано в BigDecimal"

Как я могу прочитать REAL из базы данных и заполнить значения BigDecimal этими значениями?

ОБНОВИТЬ

В настоящее время я даже не могу «притворяться, пока не сделаю» с помощью этого временного кода:

d.set_cost(42.00);

...или это:

d.set_cost((BigDecimal)42.00);

... как они оба жалуются, "ошибка: несовместимые типы: двойной не может быть преобразован в BigDecimal"

И то же самое касается этого альтернативного синтаксиса приведения, который Droidio предложенный:

d.set_cost(((BigDecimal) 42.00));

person B. Clay Shannon    schedule 11.04.2014    source источник
comment
не бросайте... создайте новый BigDecimal как d.set_cost(new BigDecimal(42.00));   -  person SnakeDoc    schedule 12.04.2014


Ответы (1)


Я не уверен, почему вы пытаетесь приводить и/или использовать операции valueOf()... просто создайте новый объект BigDecimal. У него есть конструктор, который может принимать числа с плавающей запятой, двойные числа, строки и т. д.

d.set_cost(new BigDecimal(42.00));

:)

Вы также можете изменить свои getString() операции на getBigDecimal().

Итак, как:

d.set_cost(cursor.getBigDecimal(6));

Это позволяет обойти создание временного (и ненужного) String, так как вы, похоже, все равно после получения BigDecimal в конце.

Просто имейте в виду, что если значение, которое возвращает ваш ResultSet, не может быть преобразовано в BigDecimal, например, это строка «abcd», тогда оно выдаст Exception, но это, вероятно, желательно, поскольку вы имеете дело с неверными данными.

person SnakeDoc    schedule 11.04.2014
comment
Хорошо, это избавляет меня от кладжа; исходя из этого, это может даже сработать для реальной проблемы (все равно компилируется): d.set_cost(new BigDecimal(cursor.getString(6))); Любая причина, по которой это не сработает? - person B. Clay Shannon; 12.04.2014
comment
@B.ClayShannon Я бы пропустил создание String и просто использовал бы getBigDecimal(), так как это результирующий объект, который вам в любом случае нужен. см. мое обновление выше :) - person SnakeDoc; 12.04.2014
comment
Для меня не существует такой вещи, как getBigDecimal; может быть, Androiderized Java является подмножеством BigJava? У меня есть double, blob, float, int, short и string для получения возможностей после d.set_cost(cursor. - но ни один BigDecimal не попал в поле зрения. - person B. Clay Shannon; 12.04.2014
comment
@ B.ClayShannon хм, возможно, ты прав. я не сделал много андроид сам. если такой вещи нет, то вы можете использовать любой вариант набора get_(), который вам подходит... Строки имеют тенденцию быть тяжелыми, поэтому, возможно, что-то более близкое лучше, например, Double... но у Doubles и Floats есть проблемы с точностью (очевидно)... поэтому может быть, d.set_cost(new BigDecimal(cursor.getString(6))); - ваш лучший выбор. - person SnakeDoc; 12.04.2014