diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingPattern.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingPattern.java index a738d2bc4..4e0b38b97 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingPattern.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingPattern.java @@ -28,7 +28,8 @@ public class CraftingPattern implements ICraftingPattern { private List> oreInputs = new ArrayList<>(); private List outputs = new ArrayList<>(); private List byproducts = new ArrayList<>(); - + private Integer hashCodeCached = null; + public CraftingPattern(World world, ICraftingPatternContainer container, ItemStack stack) { this.container = container; this.stack = Comparer.stripTags(stack); @@ -273,7 +274,28 @@ public class CraftingPattern implements ICraftingPattern { ", byproducts=" + byproducts + '}'; } - + + @Override + public boolean equals (Object obj) { + return this == obj || (obj instanceof ICraftingPattern && this.alike((ICraftingPattern) obj)); + } + + @Override + public int hashCode() { + if (hashCodeCached == null) { + hashCodeCached = 0; + for (ItemStack outputItemStack : this.getOutputs()) { + int itemHashCode = 0; + itemHashCode = outputItemStack.getCount(); + itemHashCode = itemHashCode * 31 + outputItemStack.getItem().hashCode(); + itemHashCode = itemHashCode * 31 + outputItemStack.getItemDamage(); + itemHashCode = itemHashCode * 31 + Objects.hashCode(outputItemStack.getTagCompound()); + hashCodeCached = hashCodeCached * 31 + itemHashCode; + } + } + return hashCodeCached; + } + @Override public boolean alike(ICraftingPattern other) { if (other == this) { diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingPatternChainList.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingPatternChainList.java index 4cb5f7567..bc2075813 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingPatternChainList.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingPatternChainList.java @@ -4,21 +4,29 @@ import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern; import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternChain; import java.util.Collection; +import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; public class CraftingPatternChainList implements Iterable { LinkedList innerChain = new LinkedList<>(); - + Map innerChainMap = new HashMap<>(); + public void add(ICraftingPattern pattern) { - int i = 0; - while (i < innerChain.size() && !innerChain.get(i).add(pattern)) { - i++; - } - if (i == innerChain.size()) { - innerChain.add(new CraftingPatternChain(pattern)); + CraftingPatternChain chain = innerChainMap.get(pattern); + if (chain == null) { + chain = new CraftingPatternChain(pattern); + innerChain.add(chain); + innerChainMap.put(pattern, chain); + } else { + if (!chain.add(pattern)) { + chain = new CraftingPatternChain(pattern); + innerChain.add(chain); + innerChainMap.put(pattern, chain); + } } } @@ -37,6 +45,7 @@ public class CraftingPatternChainList implements Iterable