Преобразование из JsArray <JavaScriptObject>в список <JSONObject>в GWT - PullRequest
7 голосов
/ 26 июня 2010

В GWT в моем коде есть JsArray .Это более или менее список объектов JSON, но его тип - JsArray .В основном он должен быть в этом формате, потому что я передаю его в качестве параметра некоторому внешнему JavaScript-коду, используя JSNI.Проблема в том, что я также хочу, чтобы это значение использовалось кодом Java.В Java я бы предпочел иметь дело с объектом типа List .Однако я не нашел хорошего способа конвертировать эти две вещи.Лучшее, что я смог сделать - это линейный обход массива для создания нового типа, который я хочу:

  public List<JSONObject> getData() {
   LinkedList<JSONObject> list = new LinkedList<JSONObject>();
   for (int i = 0; i < data.length(); ++i) {
    list.add(new JSONObject(data.get(i)));
   }
   return list;
  }

Мне ужасно не повезло?Или есть хороший быстрый способ перехода между этими двумя типами?

(возвращение JSONArray значений, возможно, тоже будет хорошо ... но что-то, что реализует интерфейс List, приятно).

Ответы [ 5 ]

5 голосов
/ 27 июня 2010

Причина, по которой вы не можете легко привести JsArray к любой реализации Java интерфейса List, заключается в том, что JsArray - это просто оболочка вокруг хорошего старого массива JavaScript.Это позволяет выполнять некоторые очень быстрые операции над ним (поскольку JSON является частью JS), но за счет того, что он не «совместим» с остальной частью кода «Java».Поэтому вы должны спросить себя, является ли скорость важным фактором и сколько вы потеряете, если преобразуете в список «Java» (который, конечно, внутренне будет просто массивом JS).

AFAIR,Я не смог найти элегантного решения этой ситуации - но в моем случае я сразу использовал объекты JsArray для создания POJO и передачи их дальше.

3 голосов
/ 31 августа 2010

Мы реализовали простую оболочку вокруг JsArray, поддерживающую всего несколько методов. Если вам не нужны все функции Списка:

public class JsArrayList<T> implements List<T> {

    private final JsArray<? extends T>  array;

    public JsArrayList(final JsArray<? extends T> array) {
        this.array = array;
    }

    public boolean add(final T e) {
        throw new RuntimeException("Not implemented.");
    }

    public boolean isEmpty() {
        return this.size() == 0;
    }

    public Iterator<T> iterator() {
        if (array == null) {
        return new EmptyIterator<T>();
    } else {
        return new JsArrayIterator<T>(array);
    }
    }

    public int size() {
        if (array == null) return 0;
        return array.length();
    }

    public T get(final int index) {
        if (array == null) { throw new IndexOutOfBoundsException("array is emtpy"); }
        return array.get(index);
    }

    ...
}

Это самое эффективное и элегантное решение, которое мы нашли.

2 голосов
/ 31 августа 2011

Основываясь на идее @EduardWirch о классе-обёртке, я создал JsList, который использует расширенную версию JsArray, чтобы обрабатывать большую часть кода изначально, вы можете получить его здесь JsList . Это позволяет создавать JsList через JsArrayExtend примерно так:

public class Values extends JavaScriptObject
{
    protected Values (){};
    static public final native JsArrayExtend getValues(String json) /*-{return eval('('+json+')');}-*/;
}

public class Value extends JavaScriptObject
{
    protected Value (){}

    public final native String getName() /*-{return this.name;}-*/;
}

...

JsList<Value> valueList=JsList<Value>(Values.getList(jsonString));

Это может быть передано любому объекту, который принимает List <> и, кажется, работает нормально. Я не проверил его полностью, поэтому, если вы обнаружите какие-либо проблемы, сообщите мне, и я обновлю его.

Первоначально я создал один из типов JavaScriptObject, который использует собственный код для работы в качестве списка, который вы можете увидеть здесь JsList расширяет JavaScriptObject , однако он нарушает систему типизации GWT и, хотя он работает для компиляций Javascript, он не делает работать иначе.

1 голос
/ 24 апреля 2014

Turbo GWT Core предлагает элегантное решение для него. Внутри пакета Js.Collections находится JsArrayList, реализация List, обертывающая собственный массив JS. Многие методы контракта проверены и работают как положено. Кроме того, он работает с любыми объектами, а не только с типами оверлеев.

Вы можете обернуть JsArray прямо как List myList = new JsArrayList(jsArray).

Turbo GWT Js.Collections также предоставляет собственную реализацию JsArray с большим количеством методов и поддержкой любого объекта. Есть JsArrayIterator, для перебора также JsArrays.

Вы можете найти больше на https://github.com/growbit/turbogwt-core.

0 голосов
/ 27 июня 2010

Я совершенно уверен, что вы пробовали метод JSONObject.cast ().

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