简体   繁体   English

检查两个集合是否包含相同元素的方式,与订单无关?

[英]Way to check if two Collections contain the same elements, independent of order?

Let say I have two different hashsets as shown below how can I check that two Hashset contain the same elements and these two hashsets are equal, independent of the order of elements in collection, please advise..!! 假设我有两个不同的哈希集,如下所示,我如何检查两个哈希集包含相同的元素,这两个哈希集是相等的,独立于集合中元素的顺序,请指教.. !!

Set set1=new HashSet();
          set.add(new Emp("Ram","Trainer",34000));
          set.add(new Emp("LalRam","Trainer",34000));

and the other one is .. 另一个是......

Set set2=new HashSet();
          set.add(new Emp("LalRam","Trainer",34000));
          set.add(new Emp("Ram","Trainer",34000));

The employee pojo is ... 员工pojo是......

class Emp //implements Comparable
{
      String name,job;
      public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getJob() {
        return job;
    }
    public void setJob(String job) {
        this.job = job;
    }
    public int getSalary() {
        return salary;
    }
    public void setSalary(int salary) {
        this.salary = salary;
    }
    int salary;
      public Emp(String n,String j,int sal)
      {
         name=n;
         job=j;
         salary=sal;
       }
      public void display()
      {
        System.out.println(name+"\t"+job+"\t"+salary);
       }



  public boolean equals(Object o)
      {

         Emp p=(Emp)o;
          return this.name.equals(p.name)&&this.job.equals(p.job) &&this.salary==p.salary;
       }
   public int hashCode()
       {
          return name.hashCode()+job.hashCode()+salary;
       }


      /* public int compareTo(Object o)
       {
          Emp e=(Emp)o;
          return this.name.compareTo(e.name);
           //return this.job.compareTo(e.job);
        //   return this.salary-e.salary;

        }*/
} 

Quoting from AbstractSet.equals(Object) javadoc: 引自AbstractSet.equals(Object)的 javadoc:

Returns true if the given object is also a set, the two sets have the same size, and every member of the given set is contained in this set. 如果给定对象也是一个集合,则返回true,两个集合具有相同的大小,并且给定集合的每个成员都包含在此集合中。 This ensures that the equals method works properly across different implementations of the Set interface. 这可确保equals方法在Set接口的不同实现中正常工作。

So it's sufficient to simply call set1.equals(set2) . 所以简单地调用set1.equals(set2)就足够了。 It will return true if and only if the set contain the same elements (assuming that you have correctly defined equals and hashCode on the objects in the sets). 当且仅当集合包含相同的元素时,它才会返回true (假设您已在集合中的对象上正确定义了equalshashCode )。

使用以下表达式。

set1.containsAll(set2) && set2.containsAll(set1)

Assuming you've defined equals and hashcode, here's one way. 假设你已经定义了equals和hashcode,这是一种方法。 Not very efficient for large members. 对大型会员来说效率不高。

  1. Check the # of elements in each. 检查每个元素的数量。 If they are not equal, you are done [not equal]. 如果他们不平等,你就完成了[不相等]。
  2. Loop through Set1. 循环通过Set1。 Check if Set2 contains each element, if not you are done [not equal]. 检查Set2是否包含每个元素,如果不是,则完成[不相等]。 otherwise if you get through the whole set, you are equal 否则,如果你通过整套,你是平等的

UPDATE: I didn't know about containsAll, which saves a lot of trouble and basically does that algorithm 更新:我不知道containsAll,这节省了很多麻烦,基本上做了算法

int s1 = set1.size();
int s2 = set2.size();
if (s1 !=s2) return false;
return set1.containsAll(set2);

If you want data equality then correctly implement equals() and hashCode() and then you can use Collection.containsAll(...) . 如果你想要数据相等,那么正确地实现equals()hashCode()然后你可以使用Collection.containsAll(...) Ofcourse, you need to make sure you call this only when both of your collections have the same number of elements otherwise you can just say they aren't equal. 当然,你需要确保只有当你的两个集合都有相同数量的元素时才调用它,否则你可以说它们不相等。

Do: 做:

  setResult = set2.clone();

  if ( setResult.retainAll( set1 ) ){

   //do something with results, since the collection had differences

}

1 - Get a collection(let's name it 'differences') that will contain items one collection has and another doesn't - 1 - 获取一个集合(让我们将它命名为“差异”),它将包含一个集合中的项目而另一个集合没有 -

Collection differences = CollectionUtils.subtract(Collection1, Collection2); 集合差异= CollectionUtils.subtract(Collection1,Collection2);

2 - Check that size == 0; 2 - 检查尺寸== 0;

If so - both collections have same elements; 如果是这样 - 两个集合都有相同的元素; if no - there's some differences and then you have to print all items that 'differences' has. 如果不是 - 存在一些差异,那么你必须打印所有“差异”的项目。

Not sure if it depends on items order. 不确定是否取决于物品订单。 I'm comparing collections in this way 我正在以这种方式比较馆藏

A verbose but (hopefully) efficient solution when you don't know the types of the collections: 当您不知道集合的类型时,这是一个冗长但(希望)有效的解决方案:

public static <T> boolean equalIgnoreOrder(Collection<T> c1, Collection<T> c2) {
    int size1 = c1.size();  // O(1) for most implementations, but we cache for the exceptions.
    if (size1 != c2.size()) {
        return false;
    }
    Set<T> set;
    Collection<T> other;
    if (c1 instanceof Set) {
        set = (Set<T>) c1;
        other = c2;
    } else if (c2 instanceof Set) {
        set = (Set<T>) c2;
        other = c1;
    } else if (size1 < 12 ) { // N^2 operation OK for small N
        return c1.containsAll(c2);
    } else {
        set = new HashSet<>(c1);
        other = c2;
    }
    return set.containsAll(other);  // O(N) for sets
}

Unless you need to implement your own method for some reason, just use h1.equals(h2) . 除非您出于某种原因需要实现自己的方法,否则只需使用h1.equals(h2) A possible implementation is described below. 下面描述可能的实现。

  1. Check if # of elements is the same. 检查元素的数量是否相同。 If not, return false. 如果没有,则返回false。
  2. Clone set 2 (if you need to keep set 2 after) 克隆设置2(如果你需要保持设置2之后)
  3. Iterate through set 1, check if each element is found in clone set 2. If found, remove from set 2. If not found, return false. 迭代集合1,检查是否在克隆集2中找到每个元素。如果找到,则从集合2中删除。如果未找到,则返回false。
  4. If you reach the end of the iterations and have matched each element of set 1, the sets are equal (since you already compared the sizes of the 2 sets). 如果到达迭代的末尾并匹配集合1的每个元素,则集合相等(因为您已经比较了2个集合的大小)。

Example: 例:

public boolean isIdenticalHashSet <A> (HashSet h1, HashSet h2) {
    if ( h1.size() != h2.size() ) {
        return false;
    }
    HashSet<A> clone = new HashSet<A>(h2); // just use h2 if you don't need to save the original h2
    Iterator it = h1.iterator();
    while (it.hasNext() ){
        A = it.next();
        if (clone.contains(A)){ // replace clone with h2 if not concerned with saving data from h2
            clone.remove(A);
        } else {
            return false;
        }
    }
    return true; // will only return true if sets are equal
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 有没有办法检查两个集合是否包含相同的元素,与订单无关? - Is there a way to check if two Collections contain the same elements, independent of order? 检查两个字符串是否包含相同顺序的相同字符 - Check whether two strings contain same characters in same order 使用自定义相等函数检查两个集合是否相同(忽略顺序) - Check if two collections are the same (ignoring order) using a custom equality function 如何检查两个对象是否包含相同的单词,而不管顺序如何? - How to check if two objects contain the same words regardless of order? 查找两个不同列表是否包含完全相同元素的简单方法? - Simple way to find if two different lists contain exactly the same elements? 检查两个集合是否包含至少一个相同元素的快速方法 - fast way to check if two sets contain at least one same element 检查两个数组是否具有相同顺序的元素 - Check whether two arrays have same elements in some order 如何 JUnit 测试这两个 List<E> 以相同的顺序包含相同的元素? - How to JUnit test that two List<E> contain the same elements in the same order? 使用Java检查两个html标记是否包含不同顺序的相同属性 - Check if two html tags contain same attributes in different order using Java Junit:如何检查 2 collections 是否与不同顺序的元素相等? - Junit: How to check if 2 collections are equals with elements in different order?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM