1

Javaのfasterxml jacksonでArrayNodeオブジェクトのサブ配列を取得する必要があります。

より明確にするために、

  1. たとえば、100個のオブジェクトを含むfasterxml jackson ArrayNodeオブジェクトがあります。
  2. たとえば、5としましょう。
  3. 以下に示すように、非常に原始的な方法でそれを行うことができます。

    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 であり、配列が含まれています。

上記は機能しますが、ArrayNode オブジェクトを 1 つずつ削除する際に、内側の while ループが「arrayNodeSize - limit」回実行されるため、非常に非効率的です。

ArrayNode またはキャストされた JsonNode 自体で実行できるサブ配列操作はありますか?

ありがとうございます。

4

2 に答える 2

2

答えてくれた「henrik」に感謝します。ジャクソンがArrayNodesのそのような機能をサポートしていないという点であなたは正しかったです。そこで、Jackson のデータバインド コードベースをダウンロードし、ArrayNodes にそのような SubArray 機能が提供されていない理由を調べました (databind 2.3.2 について言及していることに注意してください)。

内部的に、Jackson は以下のように JsonNode リストで ArrayNode を維持しています。

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

驚いたことに、何らかの理由で理解できないのですが、この含まれるリストの subList メソッドを使用して簡単に実行できる SubArray 操作が提供されていません。たとえば、以下のように、

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 原則のカプセル化に違反していることはわかっていますが、以下の投稿で説明する理由により、それを受け入れることができます。

リフレクション API は、データのカプセル化の目的そのものを壊していませんか?

于 2015-02-26T08:44:50.650 に答える
0

Jackson にはそのようなサポート ビルドはありません。

新しい ArrayNode を作成し、制限まで埋めると、ほとんどの場合、より効率的になります。

ArrayNode limited = objectMapper.createArrayNode();
for(JsonNode e : src) {
        limited.add(e);
        if (limited.size() == limit) {
            break;
        }
    }
于 2015-02-24T14:43:34.330 に答える