在java中存储无序对的列表

时间:2015-04-12 14:09:14

标签: java data-structures

说我有以下有序对(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 >>();

对于这种类型的东西,最好的选择是什么数据结构,或者我最好只创建自己的数据结构?

3 个答案:

答案 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>>

请注意,上述内容并未正确处理空值 - 您需要在构造函数中验证firstsecond都是非空的,或者可能需要处理 - 空值。

答案 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]]