我想创建可能包含重复值的集合,没有特定的顺序。
换句话说:
{ 1, 1, 2 } == { 2, 1, 1 } == { 1, 2, 1 }
事实上,我想要一组这些集合,所以如果我尝试添加这两个集合{ 1, 1, 2 }
and { 2, 1, 1 }
, 第二.add()
实际上不会做任何事情。
是否有一个标准集合已经具有这种行为方式?
如果我理解正确的话:
- ArrayList允许重复值,但有固定的顺序
- HashSet 允许任意顺序但不允许重复值
- TreeSet 确保顺序不变,但不允许重复值
是否有一个我忽略的集合允许重复值和任意或固定顺序,以便两个具有相同元素的集合被认为是相等的?
@asteri 询问我的用例。在游戏中,我有不同长度的块,可以将它们首尾相连以填充一定的距离。例如,如果距离为10,则可以用2-3-5或5-2-3或3-3-4或3-4-3或任何数量的其他排列来填充。根据可用的块,我想列出所有可能的集合来解决填补空白。
定制解决方案
@sprinter 建议创建 ArrayList 的子类。 @dasblinkenlight 和 @Dici 建议使用 Map 来存储{ Element : Count }
条目。我选择将这两个建议结合起来。下面是 TreeMap 的子类。键始终以相同的顺序存储,以确保 hashCode() 方法生成相同的值,例如使用相同的键和值。
我用过一个increment
方法可以轻松添加特定整数“值”的新出现。
package com.example.treematch;
import java.util.Map;
import java.util.TreeMap;
public class TreeMatch<K> extends TreeMap<K, Integer> {
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof TreeMatch)) {
return false;
}
TreeMatch otherMatch = (TreeMatch) other;
if (size() != otherMatch.size()) {
return false;
}
for (Object key : this.keySet()) {
if (!otherMatch.containsKey(key)) {
return false;
}
}
for (Object key : otherMatch.keySet()) {
if (!this.containsKey(key)) {
return false;
}
if (this.get(key) != otherMatch.get(key)) {
return false;
}
}
return true;
}
public void increment(K key) {
Integer value;
if (this.containsKey(key)) {
value = (this.get(key)) + 1;
} else {
value = 1;
}
this.put(key, value);
}
@Override
public int hashCode() {
int hashCode = 0;
for (Map.Entry entry : this.entrySet()) {
hashCode += entry.getKey().hashCode();
hashCode = hashCode << 1;
hashCode += entry.getValue().hashCode();
hashCode = hashCode << 1;
}
return hashCode;
}
}