/* * Copyright (c) CovertJaguar, 2014 http://railcraft.info * * This code is the property of CovertJaguar * and may only be used with explicit written * permission unless otherwise specified on the * license page at http://railcraft.info/wiki/info:license. */ package mods.railcraft.common.util.inventory; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import net.minecraft.item.ItemStack; /** * This is a custom data structure designed specifically * for using ItemStacks as keys in a Map. * * The keys index on the itemID and damage of the ItemStacks, * ignoring any other differences (NBT Tags, stackSize, etc...). * * @author CovertJaguar <http://www.railcraft.info> * @see Map * @param <V> */ public class ItemStackMap<V> implements Map<ItemStack, V> { private class EntryWrapper implements Map.Entry<ItemStack, V> { private final Map.Entry<KeyWrapper, V> entry; public EntryWrapper(Map.Entry<KeyWrapper, V> e) { entry = e; } @Override public ItemStack getKey() { return entry.getKey().getStack(); } @Override public V getValue() { return entry.getValue(); } @Override public V setValue(V value) { return entry.setValue(value); } @Override public String toString() { return getKey().getItem().getUnlocalizedName() + "=" + getValue().toString(); } } private static class KeyWrapper { private final ItemStack stack; public KeyWrapper(ItemStack stack) { this.stack = stack.copy(); } @Override public boolean equals(Object obj) { if(obj == null) { return false; } if(getClass() != obj.getClass()) { return false; } final KeyWrapper other = (KeyWrapper)obj; if(stack.getItem() != other.stack.getItem()) { return false; } if(stack.getItemDamage() != other.stack.getItemDamage()) { return false; } return true; } @Override public int hashCode() { int hash = 5; hash = 23 * hash + stack.getItem().hashCode(); hash = 23 * hash + stack.getItemDamage(); return hash; } public ItemStack getStack() { return stack.copy(); } } private final Map<KeyWrapper, V> map = new HashMap<KeyWrapper, V>(); @Override public V put(ItemStack stack, V value) { return map.put(new KeyWrapper(stack), value); } @Override public Collection<V> values() { return map.values(); } @Override public int size() { return map.size(); } @Override public V remove(Object key) { if(key instanceof ItemStack) { return map.remove(new KeyWrapper((ItemStack)key)); } return null; } @Override public boolean isEmpty() { return map.isEmpty(); } @Override public int hashCode() { return map.hashCode(); } @Override public V get(Object key) { if(key instanceof ItemStack) { return map.get(new KeyWrapper((ItemStack)key)); } return null; } @Override public boolean equals(Object o) { if(o instanceof ItemStackMap) { return map.equals(((ItemStackMap)o).map); } return false; } @Override public boolean containsValue(Object value) { return map.containsValue(value); } @Override public boolean containsKey(Object key) { if(key instanceof ItemStack) { return map.containsKey(new KeyWrapper((ItemStack)key)); } return false; } @Override public void clear() { map.clear(); } @Override public void putAll(Map<? extends ItemStack, ? extends V> m) { for(Map.Entry<? extends ItemStack, ? extends V> e : m.entrySet()) { put(e.getKey(), e.getValue()); } } @Override public Set<ItemStack> keySet() { Set<ItemStack> keySet = new HashSet<ItemStack>(); for(KeyWrapper w : map.keySet()) { keySet.add(w.getStack()); } return keySet; } @Override public Set<Map.Entry<ItemStack, V>> entrySet() { Set<Map.Entry<ItemStack, V>> entrySet = new HashSet<Map.Entry<ItemStack, V>>(); for(Map.Entry<KeyWrapper, V> entry : map.entrySet()) { entrySet.add(new EntryWrapper(entry)); } return entrySet; } }