我需要在Java的fastxml jackson中获得ArrayNode对象的子数组。

更清楚地说,


我有一个fastxml jackson ArrayNode对象,其中包含例如100个对象。
我有一个极限参数,比如说5。
可以按照以下所示的非常原始的方式进行操作,

ArrayNode arrayNodeRecProducts = (ArrayNode) recProducts;
int arrayNodeSize = arrayNodeRecProducts.size();

if (limit >= 0 && limit < arrayNodeSize) {
    while (arrayNodeRecProducts.has(limit)) {
        arrayNodeRecProducts.remove(limit);
    }
}



强制转换为ArrayNode类型的“ recProducts”对象是fasterxml jackson JsonNode,它包含一个数组。

上面的方法可以工作,但是效率很低,因为内部while循环逐一删除ArrayNode对象的次数为“ arrayNodeSize-limit”。

是否可以在ArrayNode或强制转换的JsonNode本身上执行子数组操作?

谢谢并恭祝安康..

最佳答案

感谢“ henrik”的回答,您是正确的,因为Jackson不支持ArrayNodes这样的功能。因此,我所做的就是下载了Jackson数据绑定代码库,并深入了解了为什么它们没有为ArrayNodes提供此类SubArray功能(请注意,我指的是databind 2.3.2)。

在内部,Jackson会在JsonNode列表中维护ArrayNode,如下所示,

private final List<JsonNode> _children = new ArrayList<JsonNode>();


令我惊讶的是,由于某种我无法理解的原因,他们没有提供SubArray操作,可以通过使用此包含列表的subList方法轻松完成此操作。例如如下

public List<JsonNode> subArray(int fromIndex, int toIndex) {
    return _children.subList(fromIndex, toIndex);
}


上面的方法可以使我免于遇到的麻烦,但是它根本没有包含在库中。

因此,我在代码库中所做的就是在运行时使用反射简单地侵入此私有列表,并在运行时调用subList操作,如下所示。

ArrayNode arrayNodeRecProducts = (ArrayNode) recProducts;
if (limit >= 0 && limit < arrayNodeRecProducts.size()) {
    Field innerArrayNode = ArrayNode.class.getDeclaredField("_children");
    innerArrayNode.setAccessible(true);
    List<JsonNode> innerArrayNodeChildNodes = (List<JsonNode>) innerArrayNode.get(arrayNodeRecProducts);
    List<JsonNode> limitedChildNodes = innerArrayNodeChildNodes.subList(0, limit);
    innerArrayNode.set(arrayNodeRecProducts, limitedChildNodes);
}


我知道上面的代码在所有情况下都无法正常工作,但对我来说情况很好。

同时,我知道这违反了我们严格保护的OO原则封装,但是出于下面的解释,我可以接受。

Dosen't Reflection API break the very purpose of Data encapsulation?

07-28 08:15