javacollectionsset-intersection

Intersection of all N sets in Java


I have List of TreeSet<Rate>. I need intersection of all TreeSets in the List. I checked reatainAll it is working on two sets,Correct me if i am wrong. Maximum size of List is 8.

How can i get intersection of all these sets?

public class Rate implements Comparable<Rate> {
  private double value = 0.00;
  private int restuarentID = 0;

  //setters and getters

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + restuarentID;
    long temp;
    temp = Double.doubleToLongBits(value);
    result = prime * result + (int) (temp ^ (temp >>> 32));
    return result;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj)
      return true;
    if (obj == null)
      return false;
    if (getClass() != obj.getClass())
      return false;
    Rate other = (Rate) obj;
    if (restuarentID != other.restuarentID)
      return false;
    if (Double.doubleToLongBits(value) != Double.doubleToLongBits(other.value))
      return false;
    return true;
  }

  @Override
  public int compareTo(Rate o) {
    int ret = 0;
    if (this.getValue() > o.getValue())
      ret = 1;
    if (this.getValue() < o.getValue())
      ret = -1;
    if (this.getValue() == o.getValue())
      ret = 0;
    return ret;
  }
}

Solution

  • Apply retainAll() repeatedly

    To find the intersection of all your sets (the set consisting only of elements that are a member of every set in your list), you are correct that the retainAll method is what you need. And yes, it finds the intersection of two sets. As Kayaman said in the first comment, apply it repeatedly until you have included all sets from your list in the intersection operation.

    In code:

    public static TreeSet<Rate> intersect(List<TreeSet<Rate>> setList) {
        if (setList.isEmpty()) {
            throw new IllegalArgumentException("Need at least one TreeSet in list");
        }
        Iterator<TreeSet<Rate>> it = setList.iterator();
        TreeSet<Rate> result = new TreeSet<>(it.next());
        while (it.hasNext()) {
            result.retainAll(it.next());
        }
        return result;
    }
    

    Your ordering is inconsistent with equals()

    I have trusted that you are using TreeSet because you want the semantics of TreeSet. It makes a difference. And you didn’t mention, but assuming that your TreeSet is instantiated without a Comparator, that is, it uses the natural ordering of your Rate objects, the value of your rates determine equality. Your TreeSet cannot contain two rates with the same value since the natural ordering would deem them equal, and the set would discard one.

    If instead you want your equals method used to determine equality, use a HashSet instead. This will base equality on your hashCode and equals methods and will deem objects equal only if both restuarentID and value are equal. So a HashSet can have two members with the same value if only their ID differ. And vice versa.

    Link: Comparable documentation explaining what it means for an ordering to be consistent with equals().