Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add JsonArray.asList and JsonObject.asMap view methods #2225

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 19 additions & 1 deletion gson/src/main/java/com/google/gson/JsonArray.java
Expand Up @@ -16,6 +16,7 @@

package com.google.gson;

import com.google.gson.internal.NonNullElementWrapperList;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
Expand All @@ -28,11 +29,14 @@
* elements are added is preserved. This class does not support {@code null} values. If {@code null}
* is provided as element argument to any of the methods, it is converted to a {@link JsonNull}.
*
* <p>{@code JsonArray} only implements the {@link Iterable} interface but not the {@link List}
* interface, but a {@code List} view of it can be obtained with {@link #asList()}.
Marcono1234 marked this conversation as resolved.
Show resolved Hide resolved
*
* @author Inderjeet Singh
* @author Joel Leitch
*/
public final class JsonArray extends JsonElement implements Iterable<JsonElement> {
private final List<JsonElement> elements;
private final ArrayList<JsonElement> elements;

/**
* Creates an empty JsonArray.
Expand Down Expand Up @@ -393,6 +397,20 @@ public boolean getAsBoolean() {
return getAsSingleElement().getAsBoolean();
}

/**
* Returns a mutable {@link List} view of this {@code JsonArray}. Changes to the {@code List}
* are visible for this {@code JsonArray} and the other way around.
Marcono1234 marked this conversation as resolved.
Show resolved Hide resolved
*
* <p>The {@code List} does not permit {@code null} elements. Unlike {@code JsonArray}'s
* {@code null} handling, a {@link NullPointerException} is thrown when trying to add {@code null}.
* Use {@link JsonNull} for JSON null values.
*
* @return mutable {@code List} view
*/
public List<JsonElement> asList() {
return new NonNullElementWrapperList<>(elements);
}

/**
* Returns whether the other object is equal to this. This method only considers
* the other object to be equal if it is an instance of {@code JsonArray} and has
Expand Down
18 changes: 18 additions & 0 deletions gson/src/main/java/com/google/gson/JsonObject.java
Expand Up @@ -27,6 +27,9 @@
* This class does not support {@code null} values. If {@code null} is provided as value argument
* to any of the methods, it is converted to a {@link JsonNull}.
*
* <p>{@code JsonObject} does not implement the {@link Map} interface, but a {@code Map} view
* of it can be obtained with {@link #asMap()}.
*
* @author Inderjeet Singh
* @author Joel Leitch
*/
Expand Down Expand Up @@ -208,6 +211,21 @@ public JsonObject getAsJsonObject(String memberName) {
return (JsonObject) members.get(memberName);
}

/**
* Returns a mutable {@link Map} view of this {@code JsonObject}. Changes to the {@code Map}
* are visible for this {@code JsonObject} and the other way around.
*
* <p>The {@code Map} does not permit {@code null} keys or values. Unlike {@code JsonObject}'s
* {@code null} handling, a {@link NullPointerException} is thrown when trying to add {@code null}.
* Use {@link JsonNull} for JSON null values.
*
* @return mutable {@code Map} view
*/
public Map<String, JsonElement> asMap() {
// It is safe to expose the underlying map because it disallows null keys and values
return members;
}

/**
* Returns whether the other object is equal to this. This method only considers
* the other object to be equal if it is an instance of {@code JsonObject} and has
Expand Down
@@ -0,0 +1,98 @@
package com.google.gson.internal;

import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.RandomAccess;

/**
* {@link List} which wraps another {@code List} but prevents insertion of
* {@code null} elements. Methods which only perform checks with the element
* argument (e.g. {@link #contains(Object)}) do not throw exceptions for
* {@code null} arguments.
*/
public class NonNullElementWrapperList<E> extends AbstractList<E> implements RandomAccess {
// Explicitly specify ArrayList as type to guarantee that delegate implements RandomAccess
private final ArrayList<E> delegate;

public NonNullElementWrapperList(ArrayList<E> delegate) {
this.delegate = Objects.requireNonNull(delegate);
}

@Override public E get(int index) {
return delegate.get(index);
}

@Override public int size() {
return delegate.size();
}

private E nonNull(E element) {
if (element == null) {
throw new NullPointerException("Element must be non-null");
}
return element;
}

@Override public E set(int index, E element) {
return delegate.set(index, nonNull(element));
}

@Override public void add(int index, E element) {
delegate.add(index, nonNull(element));
}

@Override public E remove(int index) {
return delegate.remove(index);
}

/* The following methods are overridden because their default implementation is inefficient */

@Override public void clear() {
delegate.clear();
}

@Override public boolean remove(Object o) {
return delegate.remove(o);
}

@Override public boolean removeAll(Collection<?> c) {
return delegate.removeAll(c);
}

@Override public boolean retainAll(Collection<?> c) {
return delegate.retainAll(c);
}

@Override public boolean contains(Object o) {
return delegate.contains(o);
}

@Override public int indexOf(Object o) {
return delegate.indexOf(o);
}

@Override public int lastIndexOf(Object o) {
return delegate.lastIndexOf(o);
}

@Override public Object[] toArray() {
return delegate.toArray();
}

@Override public <T> T[] toArray(T[] a) {
return delegate.toArray(a);
}

@Override public boolean equals(Object o) {
return delegate.equals(o);
}

@Override public int hashCode() {
return delegate.hashCode();
}

// TODO: Once Gson targets Java 8 also override List.sort
eamonnmcmanus marked this conversation as resolved.
Show resolved Hide resolved
}