说我有以下有序对(A, B), (A, C), (B, C) and (B, A)
。
在这4对中,有3对无序对。
我的问题是:java是否有一个不允许重复或回文的数据结构? ((A, B)
和(B, A)
是相同的无序集合)
Set
删除了重复的可能性,但没有删除其他部分。
Set<Entry<Integer, Integer >> values = new HashSet<Entry<Integer, Integer >>();
对于这种类型的东西,最好的选择是什么数据结构,或者我最好只创建自己的数据结构?
答案 0 :(得分:4)
java是否具有不允许重复或回文的数据结构?
不直接。
但是,您可以使用TreeSet
和自定义Comparator
合成一个,以便以具有所需属性的方式比较对。
例如:
public class Pair<T> {
public final T left;
public final T right;
...
}
/**
* Comparator that treats `(A, B)` and `(B, A)` as identical.
*/
public class PairComparator<T extends Comparable<T>>
implements Comparator<Pair<T>> {
public int compare (Pair<T> p1, Pair<T> p2) {
T p1Small, p1Large, p2Small, p2Large;
if (p1.left.compareTo(p1.right) <= 0) {
p1Small = p1.left;
p1Large = p1.right;
} else {
p1Small = p1.right;
p1Large = p1.left;
}
if (p2.left.compareTo(p2.right) <= 0) {
p2Small = p2.left;
p2Large = p2.right;
} else {
p2Small = p2.right;
p2Large = p2.left;
}
int res = p1Small.compareTo(p2Small);
if (res == 0) {
res = p1Large.compareTo(p2Large);
}
return res;
}
}
有关与HashSet
一起使用的解决方案,请参阅Jon Skeet的回答。但是,请注意,您必须实现一个非常自然的&#34; equals
的味道......如果您还需要使用&#34;自然&#34;来测试Pair
对象,这可能会有问题。等式语义。
答案 1 :(得分:2)
java是否具有不允许重复或回文的数据结构?
例如,Java有许多集合 - HashSet
。那些不允许存储多个相等的值...所以你只需要创建一个具有你想要的那种平等的类。例如:
// Note: not null-safe. (See below.)
public final class UnorderedPair<T> {
private final T first;
private final T second;
public UnorderedPair(T first, T second) {
this.first = first;
this.second = second;
}
@Override public int hashCode() {
return first.hashCode() + second.hashCode();
}
@Override public boolean equals(Object other) {
if (other == this) {
return true;
}
if (!(other instanceof UnorderedPair)) {
return false;
}
UnorderedPair<?> otherPair = (UnorderedPair<?>) other;
return (first.equals(otherPair.first) && second.equals(otherPair.second))
|| (first.equals(otherPair.second) && second.equals(otherPair.first));
}
public T getFirst() {
return first;
}
public T getSecond() {
return second;
}
}
然后您可以创建UnorderedPair<String>
值或其他值,然后创建Set<UnorderedPair<String>>
。
请注意,上述内容并未正确处理空值 - 您需要在构造函数中验证first
和second
都是非空的,或者可能需要处理 - 空值。
答案 2 :(得分:1)
java是否具有不允许重复的数据结构 回文?
正如其他提到的那样,没有。
我想到的最简单的方法是对每个列表进行排序,然后使用函数式编程简单地存储在一个集合中。示例:
List<List<String>> myListOfPair = new ArrayList<>();
myListOfPair.add(new ArrayList<>());
myListOfPair.add(new ArrayList<>());
myListOfPair.add(new ArrayList<>());
myListOfPair.add(new ArrayList<>());
myListOfPair.get(0).add("A");
myListOfPair.get(0).add("B");
myListOfPair.get(1).add("A");
myListOfPair.get(1).add("C");
myListOfPair.get(2).add("B");
myListOfPair.get(2).add("C");
myListOfPair.get(3).add("B");
myListOfPair.get(3).add("A");
System.out.println("Original list : " + myListOfPair);
Set<List<String>> mySet = new HashSet<>();
myListOfPair.stream().map(l -> {
Collections.sort(l);
return l;
}).forEach(l -> {
mySet.add(l);
});
System.out.println("New list (HashSet) : " + mySet);
那会打印
Original list : [[A, B], [A, C], [B, C], [B, A]]
New list (HashSet) : [[A, B], [B, C], [A, C]]