stream();
/**
* Visits each Entry in this TagMap This method is more efficient than {@link TagMap#iterator()}
*/
- void forEach(Consumer super TagMap.Entry> consumer);
+ void forEach(Consumer super TagMap.EntryReader> consumer);
/**
* Version of forEach that takes an extra context object that is passed as the first argument to
@@ -252,7 +256,7 @@ static Ledger ledger(int size) {
*
* The intention is to use this method to avoid using a capturing lambda
*/
- void forEach(T thisObj, BiConsumer consumer);
+ void forEach(T thisObj, BiConsumer consumer);
/**
* Version of forEach that takes two extra context objects that are passed as the first two
@@ -260,7 +264,8 @@ static Ledger ledger(int size) {
*
* The intention is to use this method to avoid using a capturing lambda
*/
- void forEach(T thisObj, U otherObj, TriConsumer consumer);
+ void forEach(
+ T thisObj, U otherObj, TriConsumer consumer);
/** Clears the TagMap */
void clear();
@@ -307,30 +312,63 @@ public boolean isRemoval() {
}
}
- final class Entry extends EntryChange implements Map.Entry {
- /*
- * Special value used for Objects that haven't been type checked yet.
- * These objects might be primitive box objects.
- */
- public static final byte ANY = 0;
+ interface EntryReader {
public static final byte OBJECT = 1;
/*
* Non-numeric primitive types
*/
public static final byte BOOLEAN = 2;
- public static final byte CHAR = 3;
+ static final byte CHAR_RESERVED = 3;
/*
* Numeric constants - deliberately arranged to allow for checking by using type >= BYTE
*/
- public static final byte BYTE = 4;
- public static final byte SHORT = 5;
+ static final byte BYTE_RESERVED = 4;
+ static final byte SHORT_RESERVED = 5;
public static final byte INT = 6;
public static final byte LONG = 7;
public static final byte FLOAT = 8;
public static final byte DOUBLE = 9;
+ String tag();
+
+ byte type();
+
+ boolean is(byte type);
+
+ boolean isNumericPrimitive();
+
+ boolean isNumber();
+
+ boolean isObject();
+
+ Object objectValue();
+
+ String stringValue();
+
+ boolean booleanValue();
+
+ int intValue();
+
+ long longValue();
+
+ float floatValue();
+
+ double doubleValue();
+
+ Map.Entry mapEntry();
+
+ Entry entry();
+ }
+
+ final class Entry extends EntryChange implements Map.Entry, EntryReader {
+ /*
+ * Special value used for Objects that haven't been type checked yet.
+ * These objects might be primitive box objects.
+ */
+ static final byte ANY = 0;
+
static Entry newAnyEntry(Map.Entry extends String, ? extends Object> entry) {
return newAnyEntry(entry.getKey(), entry.getValue());
}
@@ -400,7 +438,7 @@ static Entry newDoubleEntry(String tag, Double box) {
// no type checks are done during construction.
// Any Object entries are initially marked as type ANY, prim set to 0, and the Object put into
// obj
- // If an ANY entry is later type checked or request as a primitive, then the ANY will be
+ // If an ANY entry is later type checked or requested as a primitive, then the ANY will be
// resolved
// to the correct type.
@@ -436,10 +474,22 @@ int hash() {
return hash;
}
+ @Override
+ public Entry entry() {
+ return this;
+ }
+
+ @Override
+ public java.util.Map.Entry mapEntry() {
+ return this;
+ }
+
+ @Override
public byte type() {
return this.resolveAny();
}
+ @Override
public boolean is(byte type) {
byte curType = this.rawType;
if (curType == type) {
@@ -451,6 +501,7 @@ public boolean is(byte type) {
}
}
+ @Override
public boolean isNumericPrimitive() {
byte curType = this.rawType;
if (_isNumericPrimitive(curType)) {
@@ -462,13 +513,14 @@ public boolean isNumericPrimitive() {
}
}
+ @Override
public boolean isNumber() {
byte curType = this.rawType;
return _isNumericPrimitive(curType) || (this.rawObj instanceof Number);
}
static boolean _isNumericPrimitive(byte type) {
- return (type >= BYTE);
+ return (type >= BYTE_RESERVED);
}
private byte resolveAny() {
@@ -517,6 +569,7 @@ private void _setPrim(byte type, long prim) {
this.rawType = type;
}
+ @Override
public boolean isObject() {
return this.is(OBJECT);
}
@@ -525,6 +578,7 @@ public boolean isRemoval() {
return false;
}
+ @Override
public Object objectValue() {
if (this.rawObj != null) {
return this.rawObj;
@@ -562,6 +616,7 @@ public Object objectValue() {
return this.rawObj;
}
+ @Override
public boolean booleanValue() {
byte type = this.rawType;
@@ -597,6 +652,7 @@ public boolean booleanValue() {
return false;
}
+ @Override
public int intValue() {
byte type = this.rawType;
@@ -632,6 +688,7 @@ public int intValue() {
return 0;
}
+ @Override
public long longValue() {
byte type = this.rawType;
@@ -667,6 +724,7 @@ public long longValue() {
return 0;
}
+ @Override
public float floatValue() {
byte type = this.rawType;
@@ -702,6 +760,7 @@ public float floatValue() {
return 0F;
}
+ @Override
public double doubleValue() {
byte type = this.rawType;
@@ -737,6 +796,7 @@ public double doubleValue() {
return 0D;
}
+ @Override
public String stringValue() {
String strCache = this.strCache;
if (strCache != null) {
@@ -1267,8 +1327,8 @@ public boolean containsKey(Object key) {
@Override
public boolean containsValue(Object value) {
// This could be optimized - but probably isn't called enough to be worth it
- for (Entry entry : this) {
- if (entry.objectValue().equals(value)) return true;
+ for (EntryReader entryReader : this) {
+ if (entryReader.objectValue().equals(value)) return true;
}
return false;
}
@@ -1278,11 +1338,21 @@ public Set keySet() {
return new Keys(this);
}
+ @Override
+ public Iterator tagIterator() {
+ return new KeysIterator(this);
+ }
+
@Override
public Collection