如何使用Jackson将JSON数组反序列化为单链表

如何使用Jackson将JSON数组反序列化为单链表,jackson,Jackson,我想将JSON数组反序列化为Java中的单链表 单链表的定义如下: public class SinglyLinkedListNode<T> { public T value; public SinglyLinkedListNode next; public SinglyLinkedListNode(final T value) { this.value = value; } } import java.util.*; import

我想将JSON数组反序列化为Java中的单链表

单链表的定义如下:

public class SinglyLinkedListNode<T> {
    public T value;
    public SinglyLinkedListNode next;
    public SinglyLinkedListNode(final T value) {
        this.value = value;
    }
}
import java.util.*;
import java.util.function.Consumer;

/**
 * Singly Linked List.
 *
 * <p>As to singly linked list, a node can be viewed as a single node,
 * and it can be viewed as a list too.</p>
 *
 * @param <E> the type of elements held in this collection
 * @see java.util.LinkedList
 */
public class SinglyLinkedListNode<E>
    extends AbstractSequentialList<E>
    implements Cloneable, java.io.Serializable {
    public E value;
    public SinglyLinkedListNode<E> next;

    /**
     * Constructs an empty list.
     */
    public SinglyLinkedListNode() {
        value = null;
        next = null;
    }

    /**
     * Constructs an list with one elment.
     */
    public SinglyLinkedListNode(final E value) {
        this.value = value;
        next = null;
    }

    /**
     * Constructs a list containing the elements of the specified
     * collection, in the order they are returned by the collection's
     * iterator.
     *
     * @param  c the collection whose elements are to be placed into this list
     * @throws NullPointerException if the specified collection is null
     */
    public SinglyLinkedListNode(Collection<? extends E> c) {
        this();
        addAll(c);
    }

    /**
     * Links e as last element.
     */
    void linkLast(E e) {
        final SinglyLinkedListNode<E> l = last();
        final SinglyLinkedListNode<E> newNode = new SinglyLinkedListNode<>(e);
        if (l == null)
            this.value = e;
        else
            l.next = newNode;
        modCount++;
    }

    /**
     * Inserts element e before non-null Node succ.
     */
    void linkBefore(E e, SinglyLinkedListNode<E> succ) {
        assert succ != null;
        final SinglyLinkedListNode<E> prev = this.previous(succ);
        final SinglyLinkedListNode<E> newNode = new SinglyLinkedListNode<>(e);
        if (prev == null)
            this.value = e;
        else
            prev.next = newNode;
        modCount++;
    }

    /**
     * Return the node before x.
     *
     * @param x current node
     * @return the node before x
     */
    private SinglyLinkedListNode<E> previous(final SinglyLinkedListNode<E> x) {
        assert (x != null);
        if (size() < 2)  return null;
        if (this == x) return null;

        SinglyLinkedListNode<E> prev = new SinglyLinkedListNode<>();
        prev.next = this;
        SinglyLinkedListNode<E> cur = this;
        while (cur != x) {
            prev = prev.next;
            cur = cur.next;
        }
        return prev;
    }

    /**
     * Return the last node.
     * @return the last node.
     */
    private SinglyLinkedListNode<E> last() {
        if (size() == 0) return null;
        if (size() == 1) return this;

        SinglyLinkedListNode<E> prev = new SinglyLinkedListNode<>();
        prev.next = this;
        SinglyLinkedListNode<E> cur = this;
        while (cur != null) {
            prev = prev.next;
            cur = cur.next;
        }
        return prev;
    }

    /**
     * Unlinks non-null node x.
     */
    E unlink(SinglyLinkedListNode<E> x) {
        assert x != null;
        final E element = x.value;
        final SinglyLinkedListNode<E> next = x.next;
        final SinglyLinkedListNode<E> prev = previous(x);

        if (prev == null) {
            this.value = next.value;
            this.next = next.next;
        } else {
            prev.next = next;
        }

        x.next = null;

        modCount++;
        return element;
    }

    /**
     * @inheritDoc
     */
    public ListIterator<E> listIterator(int index) {
        checkPositionIndex(index);
        return new ListItr(index);
    }


    private class ListItr implements ListIterator<E> {
        private SinglyLinkedListNode<E> lastReturned;
        private SinglyLinkedListNode<E> next;
        private int nextIndex;
        private int expectedModCount = modCount;

        ListItr(int index) {
            assert isPositionIndex(index);
            next = (index == size()) ? null : node(index);
            nextIndex = index;
        }

        public boolean hasNext() {
            return nextIndex < size();
        }

        public E next() {
            checkForComodification();
            if (!hasNext())
                throw new NoSuchElementException();

            lastReturned = next;
            next = next.next;
            nextIndex++;
            return lastReturned.value;
        }

        public boolean hasPrevious() {
            return nextIndex > 0;
        }

        public E previous() {
            throw new UnsupportedOperationException();
        }

        public int nextIndex() {
            return nextIndex;
        }

        public int previousIndex() {
            return nextIndex - 1;
        }

        public void remove() {
            checkForComodification();
            if (lastReturned == null)
                throw new IllegalStateException();

            unlink(lastReturned);

            nextIndex--;
            lastReturned = null;
            expectedModCount++;
        }

        public void set(E e) {
            if (lastReturned == null)
                throw new IllegalStateException();
            checkForComodification();
            lastReturned.value = e;
        }

        public void add(E e) {
            checkForComodification();
            lastReturned = null;
            if (next == null)
                linkLast(e);
            else
                linkBefore(e, next);
            nextIndex++;
            expectedModCount++;
        }

        public void forEachRemaining(Consumer<? super E> action) {
            Objects.requireNonNull(action);
            while (modCount == expectedModCount && nextIndex < size()) {
                action.accept(next.value);
                lastReturned = next;
                next = next.next;
                nextIndex++;
            }
            checkForComodification();
        }

        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }

    /**
     * @inheritDoc
     */
    public int size() {
        int size = 0;
        if (value == null) return size;

        SinglyLinkedListNode<E> cur = this;
        while (cur != null) {
            size++;
            cur = cur.next;
        }
        return size;
    }

    private void checkPositionIndex(int index) {
        if (!isPositionIndex(index))
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

    /**
     * Returns the (non-null) Node at the specified element index.
     */
    SinglyLinkedListNode<E> node(int index) {
        assert isElementIndex(index);

        SinglyLinkedListNode<E> x = this;
        for (int i = 0; i < index; i++)
            x = x.next;
        return x;
    }

    /**
     * Tells if the argument is the index of an existing element.
     */
    private boolean isElementIndex(int index) {
        return index >= 0 && index < size();
    }

    /**
     * Tells if the argument is the index of a valid position for an
     * iterator or an add operation.
     */
    private boolean isPositionIndex(int index) {
        return index >= 0 && index <= size();
    }

    /**
     * Constructs an IndexOutOfBoundsException detail message.
     * Of the many possible refactorings of the error handling code,
     * this "outlining" performs best with both server and client VMs.
     */
    private String outOfBoundsMsg(int index) {
        return "Index: "+index+", Size: " + size();
    }
}
此外,我希望
SinglyLinkedListNode
成为与
ArrayList
相同的一等公民,可以在各种组合中使用,例如
HashSet
SinglyLinkedListNode

例如,如果我想将
[[1,2,3],[4,5,6]]
反序列化到
数组列表中,会发生什么


据我所知,一个扩展了
JsonDeserializer
的定制反序列化程序不足以做到这一点。

例如,当您希望将其反序列化为
ArrayList
时。您的代码指定了预期的类型。因此,如果注册了
SingleLinkedListNode
的反序列化程序,它应该会成功。

我从@Tatu Saloranta获得正确答案

答案很简单:只要实现
java.util.List
接口,Jackson就会自动在JSON数组和
SingleLinkedListNode
之间进行序列化/反序列化

因此,我为
SingleyLinkedListNode
实现了
java.util.List
接口,代码如下:

public class SinglyLinkedListNode<T> {
    public T value;
    public SinglyLinkedListNode next;
    public SinglyLinkedListNode(final T value) {
        this.value = value;
    }
}
import java.util.*;
import java.util.function.Consumer;

/**
 * Singly Linked List.
 *
 * <p>As to singly linked list, a node can be viewed as a single node,
 * and it can be viewed as a list too.</p>
 *
 * @param <E> the type of elements held in this collection
 * @see java.util.LinkedList
 */
public class SinglyLinkedListNode<E>
    extends AbstractSequentialList<E>
    implements Cloneable, java.io.Serializable {
    public E value;
    public SinglyLinkedListNode<E> next;

    /**
     * Constructs an empty list.
     */
    public SinglyLinkedListNode() {
        value = null;
        next = null;
    }

    /**
     * Constructs an list with one elment.
     */
    public SinglyLinkedListNode(final E value) {
        this.value = value;
        next = null;
    }

    /**
     * Constructs a list containing the elements of the specified
     * collection, in the order they are returned by the collection's
     * iterator.
     *
     * @param  c the collection whose elements are to be placed into this list
     * @throws NullPointerException if the specified collection is null
     */
    public SinglyLinkedListNode(Collection<? extends E> c) {
        this();
        addAll(c);
    }

    /**
     * Links e as last element.
     */
    void linkLast(E e) {
        final SinglyLinkedListNode<E> l = last();
        final SinglyLinkedListNode<E> newNode = new SinglyLinkedListNode<>(e);
        if (l == null)
            this.value = e;
        else
            l.next = newNode;
        modCount++;
    }

    /**
     * Inserts element e before non-null Node succ.
     */
    void linkBefore(E e, SinglyLinkedListNode<E> succ) {
        assert succ != null;
        final SinglyLinkedListNode<E> prev = this.previous(succ);
        final SinglyLinkedListNode<E> newNode = new SinglyLinkedListNode<>(e);
        if (prev == null)
            this.value = e;
        else
            prev.next = newNode;
        modCount++;
    }

    /**
     * Return the node before x.
     *
     * @param x current node
     * @return the node before x
     */
    private SinglyLinkedListNode<E> previous(final SinglyLinkedListNode<E> x) {
        assert (x != null);
        if (size() < 2)  return null;
        if (this == x) return null;

        SinglyLinkedListNode<E> prev = new SinglyLinkedListNode<>();
        prev.next = this;
        SinglyLinkedListNode<E> cur = this;
        while (cur != x) {
            prev = prev.next;
            cur = cur.next;
        }
        return prev;
    }

    /**
     * Return the last node.
     * @return the last node.
     */
    private SinglyLinkedListNode<E> last() {
        if (size() == 0) return null;
        if (size() == 1) return this;

        SinglyLinkedListNode<E> prev = new SinglyLinkedListNode<>();
        prev.next = this;
        SinglyLinkedListNode<E> cur = this;
        while (cur != null) {
            prev = prev.next;
            cur = cur.next;
        }
        return prev;
    }

    /**
     * Unlinks non-null node x.
     */
    E unlink(SinglyLinkedListNode<E> x) {
        assert x != null;
        final E element = x.value;
        final SinglyLinkedListNode<E> next = x.next;
        final SinglyLinkedListNode<E> prev = previous(x);

        if (prev == null) {
            this.value = next.value;
            this.next = next.next;
        } else {
            prev.next = next;
        }

        x.next = null;

        modCount++;
        return element;
    }

    /**
     * @inheritDoc
     */
    public ListIterator<E> listIterator(int index) {
        checkPositionIndex(index);
        return new ListItr(index);
    }


    private class ListItr implements ListIterator<E> {
        private SinglyLinkedListNode<E> lastReturned;
        private SinglyLinkedListNode<E> next;
        private int nextIndex;
        private int expectedModCount = modCount;

        ListItr(int index) {
            assert isPositionIndex(index);
            next = (index == size()) ? null : node(index);
            nextIndex = index;
        }

        public boolean hasNext() {
            return nextIndex < size();
        }

        public E next() {
            checkForComodification();
            if (!hasNext())
                throw new NoSuchElementException();

            lastReturned = next;
            next = next.next;
            nextIndex++;
            return lastReturned.value;
        }

        public boolean hasPrevious() {
            return nextIndex > 0;
        }

        public E previous() {
            throw new UnsupportedOperationException();
        }

        public int nextIndex() {
            return nextIndex;
        }

        public int previousIndex() {
            return nextIndex - 1;
        }

        public void remove() {
            checkForComodification();
            if (lastReturned == null)
                throw new IllegalStateException();

            unlink(lastReturned);

            nextIndex--;
            lastReturned = null;
            expectedModCount++;
        }

        public void set(E e) {
            if (lastReturned == null)
                throw new IllegalStateException();
            checkForComodification();
            lastReturned.value = e;
        }

        public void add(E e) {
            checkForComodification();
            lastReturned = null;
            if (next == null)
                linkLast(e);
            else
                linkBefore(e, next);
            nextIndex++;
            expectedModCount++;
        }

        public void forEachRemaining(Consumer<? super E> action) {
            Objects.requireNonNull(action);
            while (modCount == expectedModCount && nextIndex < size()) {
                action.accept(next.value);
                lastReturned = next;
                next = next.next;
                nextIndex++;
            }
            checkForComodification();
        }

        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }

    /**
     * @inheritDoc
     */
    public int size() {
        int size = 0;
        if (value == null) return size;

        SinglyLinkedListNode<E> cur = this;
        while (cur != null) {
            size++;
            cur = cur.next;
        }
        return size;
    }

    private void checkPositionIndex(int index) {
        if (!isPositionIndex(index))
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

    /**
     * Returns the (non-null) Node at the specified element index.
     */
    SinglyLinkedListNode<E> node(int index) {
        assert isElementIndex(index);

        SinglyLinkedListNode<E> x = this;
        for (int i = 0; i < index; i++)
            x = x.next;
        return x;
    }

    /**
     * Tells if the argument is the index of an existing element.
     */
    private boolean isElementIndex(int index) {
        return index >= 0 && index < size();
    }

    /**
     * Tells if the argument is the index of a valid position for an
     * iterator or an add operation.
     */
    private boolean isPositionIndex(int index) {
        return index >= 0 && index <= size();
    }

    /**
     * Constructs an IndexOutOfBoundsException detail message.
     * Of the many possible refactorings of the error handling code,
     * this "outlining" performs best with both server and client VMs.
     */
    private String outOfBoundsMsg(int index) {
        return "Index: "+index+", Size: " + size();
    }
}
import java.util.*;
导入java.util.function.Consumer;
/**
*单链表。
*
*对于单链表,一个节点可以看作是一个节点,
*它也可以被看作是一个列表

* *@param此集合中包含的元素类型 *@see java.util.LinkedList */ 公共类SingleLinkedListNode 扩展抽象顺序列表 实现可克隆、java.io.Serializable{ 公共价值观; 公共SingleLinkedListNode下一步; /** *构造一个空列表。 */ 公共SingleLinkedListNode(){ 值=空; next=null; } /** *用一个元素构造一个列表。 */ 公共SingleLinkedListNode(最终E值){ 这个值=值; next=null; } /** *构造一个包含指定元素的列表 *集合,按集合的 *迭代器。 * *@param c要将其元素放入此列表的集合 *如果指定的集合为空,@将引发NullPointerException */
public SinglyLinkedListNode(集合)您显然需要为
SinglyLinkedListNode
编写自己的反序列化程序:定制的反序列化程序可能不够,我已更新了我的问题。