简体   繁体   中英

How two zip two sets into a map in Java

I have a Set A:

[{name: a,value: 10},
 {name: b,value: 11}]

and Set B:

[{name: a,value: 100},
 {name: b,value: 110}]

Then, I want get Map C:

{{name: a,value: 10}:{name: a,value: 100},
 {name: b,value: 11}:{name: b,value: 110}}

The key and the the value of each Entry in Map C are equal, which means that the key and the value has the same "name", through different "value"s. I found guava's Sets is useful, but lack of such functions.

I know this is one way to do that:

public static <T> Map<T, T> zip(Set<T> s1, Set<T> s2) {
    Map<T, T> map = new HashMap<>();
    for (T e1 : s1) {
        for (T e2 : s2) {
            if (e1.equals(e2)) {
                map.put(e1, e2);
                break;
            }
        }
    }
    return map;
}

Is there any convenient way to zip two sets in Java?

You could try this, for this to work override equals and hashcode with field name

public static <T> Map<T, T> zip(Set<T> s1, Set<T> s2) {
    return s1.stream()
             .filter(s2::contains)
             .collect(Collectors.toMap(k -> k, v -> s2.stream().filter(s -> s.equals(v)).findFirst().get()));
}

The implementation you specified has complexity O(n^2). You can write it as O(n) as follows:

public static <T> Map<T, T> zip(Set<T> s1, Set<T> s2) {
    Map<T, T> map = new HashMap<>();
    for (T e1 : s1) {
      T e2 = s2.get(e1) {
         if (e1.equals(e2)) {
            map.put(e1, e2);
            break;
        }
    }
    return map;
}

This is O(n) because get() uses hashing to find the element. For this to work correctly, you need to implement hashCode() and equals() for the actual type passed as T to behave properly:

class Actual {
  private String name;
  private String value;
  ...
  public int hashCode() { 
    return name.hashCode()
  }
  public boolean equals(Object o) {
    if (!(o instanceof Actual)) {
      return false;
    }
    Actual other = (Actual)o;
    return name.equals(other.name);
  } 
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM