ArrayNode: make _children final
Simplifies quite a lot of code in the process.
diff --git a/src/main/java/com/fasterxml/jackson/databind/node/ArrayNode.java b/src/main/java/com/fasterxml/jackson/databind/node/ArrayNode.java
index 845058a..41c22f7 100644
--- a/src/main/java/com/fasterxml/jackson/databind/node/ArrayNode.java
+++ b/src/main/java/com/fasterxml/jackson/databind/node/ArrayNode.java
@@ -17,14 +17,13 @@
public class ArrayNode
extends ContainerNode<ArrayNode>
{
- // before 2.1, was explicitly `ArrayList`
- protected List<JsonNode> _children;
+ protected final List<JsonNode> _children = new ArrayList<JsonNode>();
public ArrayNode(JsonNodeFactory nc) { super(nc); }
protected ArrayNode(JsonNodeFactory nc, List<JsonNode> children) {
super(nc);
- _children = children;
+ _children.addAll(children);
}
// note: co-variant to allow caller-side type safety
@@ -47,14 +46,12 @@
*/
protected ArrayNode _defaultDeepCopy()
{
- if (_children == null) {
- return new ArrayNode(_nodeFactory);
- }
final int len = _children.size();
- List<JsonNode> newKids = _createList(Math.max(4, len));
- for (int i = 0; i < len; ++i) {
- newKids.add(_children.get(i).deepCopy());
- }
+ final List<JsonNode> newKids = new ArrayList<JsonNode>(len);
+
+ for (JsonNode child : _children)
+ newKids.add(child.deepCopy());
+
return new ArrayNode(_nodeFactory, newKids);
}
@@ -75,22 +72,19 @@
@Override
public int size()
{
- return (_children == null) ? 0 : _children.size();
+ return _children.size();
}
@Override
public Iterator<JsonNode> elements()
{
- if (_children == null) {
- return EmptyIterator.instance();
- }
return _children.iterator();
}
@Override
public JsonNode get(int index)
{
- if (index >= 0 && (_children != null) && index < _children.size()) {
+ if (index >= 0 && index < _children.size()) {
return _children.get(index);
}
return null;
@@ -105,7 +99,7 @@
@Override
public JsonNode path(int index)
{
- if (index >= 0 && (_children != null) && index < _children.size()) {
+ if (index >= 0 && index < _children.size()) {
return _children.get(index);
}
return MissingNode.getInstance();
@@ -122,15 +116,13 @@
throws IOException, JsonProcessingException
{
jg.writeStartArray();
- if (_children != null) {
- for (JsonNode n : _children) {
- /* 17-Feb-2009, tatu: Can we trust that all nodes will always
- * extend BaseJsonNode? Or if not, at least implement
- * JsonSerializable? Let's start with former, change if
- * we must.
- */
- ((BaseJsonNode)n).serialize(jg, provider);
- }
+ for (JsonNode n : _children) {
+ /* 17-Feb-2009, tatu: Can we trust that all nodes will always
+ * extend BaseJsonNode? Or if not, at least implement
+ * JsonSerializable? Let's start with former, change if
+ * we must.
+ */
+ ((BaseJsonNode)n).serialize(jg, provider);
}
jg.writeEndArray();
}
@@ -141,10 +133,8 @@
throws IOException, JsonProcessingException
{
typeSer.writeTypePrefixForArray(this, jg);
- if (_children != null) {
- for (JsonNode n : _children) {
- ((BaseJsonNode)n).serialize(jg, provider);
- }
+ for (JsonNode n : _children) {
+ ((BaseJsonNode)n).serialize(jg, provider);
}
typeSer.writeTypeSuffixForArray(this, jg);
}
@@ -158,12 +148,10 @@
@Override
public JsonNode findValue(String fieldName)
{
- if (_children != null) {
- for (JsonNode node : _children) {
- JsonNode value = node.findValue(fieldName);
- if (value != null) {
- return value;
- }
+ for (JsonNode node : _children) {
+ JsonNode value = node.findValue(fieldName);
+ if (value != null) {
+ return value;
}
}
return null;
@@ -172,10 +160,8 @@
@Override
public List<JsonNode> findValues(String fieldName, List<JsonNode> foundSoFar)
{
- if (_children != null) {
- for (JsonNode node : _children) {
- foundSoFar = node.findValues(fieldName, foundSoFar);
- }
+ for (JsonNode node : _children) {
+ foundSoFar = node.findValues(fieldName, foundSoFar);
}
return foundSoFar;
}
@@ -183,10 +169,8 @@
@Override
public List<String> findValuesAsText(String fieldName, List<String> foundSoFar)
{
- if (_children != null) {
- for (JsonNode node : _children) {
- foundSoFar = node.findValuesAsText(fieldName, foundSoFar);
- }
+ for (JsonNode node : _children) {
+ foundSoFar = node.findValuesAsText(fieldName, foundSoFar);
}
return foundSoFar;
}
@@ -194,24 +178,20 @@
@Override
public ObjectNode findParent(String fieldName)
{
- if (_children != null) {
- for (JsonNode node : _children) {
- JsonNode parent = node.findParent(fieldName);
- if (parent != null) {
- return (ObjectNode) parent;
- }
+ for (JsonNode node : _children) {
+ JsonNode parent = node.findParent(fieldName);
+ if (parent != null) {
+ return (ObjectNode) parent;
}
}
- return null;
+ return null;
}
@Override
public List<JsonNode> findParents(String fieldName, List<JsonNode> foundSoFar)
{
- if (_children != null) {
- for (JsonNode node : _children) {
- foundSoFar = node.findParents(fieldName, foundSoFar);
- }
+ for (JsonNode node : _children) {
+ foundSoFar = node.findParents(fieldName, foundSoFar);
}
return foundSoFar;
}
@@ -238,7 +218,10 @@
if (value == null) { // let's not store 'raw' nulls but nodes
value = nullNode();
}
- return _set(index, value);
+ if (index < 0 || index >= _children.size()) {
+ throw new IndexOutOfBoundsException("Illegal index "+ index +", array size "+size());
+ }
+ return _children.set(index, value);
}
/**
@@ -265,13 +248,7 @@
*/
public ArrayNode addAll(ArrayNode other)
{
- int len = other.size();
- if (len > 0) {
- if (_children == null) {
- _children = _createList(len+2);
- }
- other.addContentsTo(_children);
- }
+ _children.addAll(other._children);
return this;
}
@@ -284,13 +261,7 @@
*/
public ArrayNode addAll(Collection<JsonNode> nodes)
{
- int len = nodes.size();
- if (len > 0) {
- if (_children == null) {
- _children = _createList(nodes.size());
- }
- _children.addAll(nodes);
- }
+ _children.addAll(nodes);
return this;
}
@@ -321,7 +292,7 @@
*/
public JsonNode remove(int index)
{
- if (index >= 0 && (_children != null) && index < _children.size()) {
+ if (index >= 0 && index < _children.size()) {
return _children.remove(index);
}
return null;
@@ -336,7 +307,7 @@
@Override
public ArrayNode removeAll()
{
- _children = null;
+ _children.clear();
return this;
}
@@ -764,11 +735,7 @@
protected void addContentsTo(List<JsonNode> dst)
{
- if (_children != null) {
- for (JsonNode n : _children) {
- dst.add(n);
- }
- }
+ dst.addAll(_children);
}
/*
@@ -813,70 +780,16 @@
{
if (o == this) return true;
if (o == null) return false;
- if (o.getClass() != getClass() && !(o instanceof ArrayNode)) {
+ if (!(o instanceof ArrayNode)) {
return false;
}
- /* This is bit convoluted, but the goal is to make it possible to
- * fully override equality comparison, even though it is
- * asymmetric (i.e. can be called on either side, but we
- * want behavior to match).
- */
- return _equals((ArrayNode) o);
- }
-
- /**
- * Method that sub-classes should override, if equality comparison
- * needs additional verification beyond defaults.
- *
- * @since 2.1
- */
- protected boolean _equals(ArrayNode other)
- {
- return _stdEquals(other)
- &&_customEquals(other)
- && other._customEquals(this)
- ;
- }
-
- /**
- * Method that sub-classes should override, if equality comparison
- * needs additional verification beyond defaults.
- *
- * @since 2.1
- */
- protected boolean _customEquals(ArrayNode other) {
- return true;
- }
-
- /**
- * Standard equality check, which may also be overridden by
- * sub-classes if necessary (but usually isn't).
- *
- * @since 2.1
- */
- protected final boolean _stdEquals(ArrayNode other)
- {
- if (_children == null || _children.size() == 0) {
- return other.size() == 0;
- }
- return other._sameChildren(_children);
+ return _children.equals(((ArrayNode) o)._children);
}
@Override
public int hashCode()
{
- int hash;
- if (_children == null) {
- hash = 1;
- } else {
- hash = _children.size();
- for (JsonNode n : _children) {
- if (n != null) {
- hash ^= n.hashCode();
- }
- }
- }
- return hash;
+ return _children.hashCode();
}
@@ -885,13 +798,11 @@
{
StringBuilder sb = new StringBuilder(16 + (size() << 4));
sb.append('[');
- if (_children != null) {
- for (int i = 0, len = _children.size(); i < len; ++i) {
- if (i > 0) {
- sb.append(',');
- }
- sb.append(_children.get(i).toString());
+ for (int i = 0, len = _children.size(); i < len; ++i) {
+ if (i > 0) {
+ sb.append(',');
}
+ sb.append(_children.get(i).toString());
}
sb.append(']');
return sb.toString();
@@ -903,30 +814,14 @@
/**********************************************************
*/
- public JsonNode _set(int index, JsonNode value)
- {
- if (_children == null || index < 0 || index >= _children.size()) {
- throw new IndexOutOfBoundsException("Illegal index "+index+", array size "+size());
- }
- return _children.set(index, value);
- }
-
private ArrayNode _add(JsonNode node)
{
- if (_children == null) {
- _children = _createList();
- }
_children.add(node);
return this;
}
private ArrayNode _insert(int index, JsonNode node)
{
- if (_children == null) {
- _children = _createList();
- _children.add(node);
- return this;
- }
if (index < 0) {
_children.add(0, node);
} else if (index >= _children.size()) {
@@ -936,22 +831,4 @@
}
return this;
}
-
- /**
- * Note: this method gets called iff <code>otherChildren</code>
- * is non-empty
- */
- private boolean _sameChildren(List<JsonNode> otherChildren)
- {
- int len = otherChildren.size();
- if (this.size() != len) { // important: call size() to handle case of null list...
- return false;
- }
- for (int i = 0; i < len; ++i) {
- if (!_children.get(i).equals(otherChildren.get(i))) {
- return false;
- }
- }
- return true;
- }
}