在 GWT 中从 JsArray<JavaScriptObject> 转换为 List<JSONObject>
Posted
技术标签:
【中文标题】在 GWT 中从 JsArray<JavaScriptObject> 转换为 List<JSONObject>【英文标题】:Converting from JsArray<JavaScriptObject> to List<JSONObject> in GWT 【发布时间】:2010-06-26 18:44:59 【问题描述】:在 GWT 中,我的代码中有一个 JsArray
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 接口的东西很好)。
【问题讨论】:
【参考方案1】:之所以不能轻易地将JsArray
转换为List
接口的任何Java 实现,是因为JsArray
只是一个好的ol' JavaScript 数组的包装器。这允许对其进行一些非常快速的操作(因为 JSON 是 JS 的一部分),但代价是与“Java”代码的其余部分不“兼容”。所以你必须问问自己,速度是否是一个重要因素,如果你转换为“Java”列表(当然,在内部只是一个 JS 数组),你会损失多少。
AFAIR,我还没有找到任何优雅的解决方案来解决这种情况 - 但就我而言,我立即使用 JsArray 对象来创建 POJO 并进一步传递它们。
【讨论】:
【参考方案2】:我们围绕 JsArray
实现了一个简单的包装器,只支持几个方法。如果您不需要 List 的所有功能:
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);
...
这是我们找到的最高效、最优雅的解决方案。
【讨论】:
你能分享完整的实现吗?谢谢! 类的其余部分与我发布的截图几乎相同。这个答案太长了。【参考方案3】:根据@EduardWirch 的包装类想法,我创建了JsList,它使用JsArray 的扩展版本来处理大部分代码,您可以在JsList 获得它。它允许像这样通过 JsArrayExtend 创建 JsList:
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 extends JavaScriptObject,但是它破坏了 GWT 类型系统,虽然它适用于 Javascript 编译,但它在其他情况下不起作用。
【讨论】:
【参考方案4】:Turbo GWT Core 为其提供了优雅的解决方案。在它的 Js.Collections 包中,有 JsArrayList,一个包装原生 JS 数组的 List 实现。合同的许多方法都经过测试并按预期工作。此外,它适用于任何类型的 Object,而不仅仅是 Overlay 类型。
你可以像List myList = new JsArrayList(jsArray)
一样直接包装一个JsArray。
Turbo GWT Js.Collections 还提供了自己的 JsArray 实现,具有更多方法并支持任何对象。还有一个 JsArrayIterator,也用于迭代 JsArrays。
您可以在https://github.com/growbit/turbogwt-core 找到更多信息。
【讨论】:
以上是关于在 GWT 中从 JsArray<JavaScriptObject> 转换为 List<JSONObject>的主要内容,如果未能解决你的问题,请参考以下文章
软件架构分解LinkedIn日志系统GWT HTML5支持——架构周报